0 | module System.Posix.File.ReadRes
2 | import Derive.Prelude
3 | import Data.Linear.Token
6 | import public Control.Monad.Resource
7 | import public Data.Buffer
8 | import public Data.Buffer.Core
9 | import public Data.ByteString
10 | import public Data.C.Ptr
11 | import public System.Posix.Errno
14 | %language ElabReflection
19 | data ReadRes : Type -> Type where
21 | Interrupted : ReadRes a
34 | Res : (res : a) -> ReadRes a
36 | %runElab derive "ReadRes" [Show,Eq]
39 | Functor ReadRes where
40 | map f Interrupted = Interrupted
41 | map f NoData = NoData
42 | map f Closed = Closed
44 | map f (Res res) = Res (f res)
47 | Foldable ReadRes where
48 | foldr f v (Res r) = f r v
52 | Traversable ReadRes where
53 | traverse f Interrupted = pure Interrupted
54 | traverse f NoData = pure NoData
55 | traverse f Closed = pure Closed
56 | traverse f EOI = pure EOI
57 | traverse f (Res res) = Res <$> f res
60 | fromErr : Errno -> EPrim (ReadRes a)
62 | if err == EAGAIN then R NoData t
63 | else if err == EWOULDBLOCK then R NoData t
64 | else if err == EINTR then R Interrupted t
65 | else if err == EPIPE then R Closed t
66 | else E (inject err) t
79 | cptrOf1 : (0 a : Type) -> SizeOf a => Nat -> F1 World CPtr
81 | let sz := cast n * sizeof a
82 | p := prim__malloc sz
83 | in CP sz (prim__malloc sz) # t
86 | cptrOf : HasIO io => (0 a : Type) -> SizeOf a => Nat -> io CPtr
87 | cptrOf a = runIO . cptrOf1 a
90 | cptr1 : Nat -> F1 World CPtr
91 | cptr1 = cptrOf1 Bits8
94 | cptr : HasIO io => Nat -> io CPtr
95 | cptr = runIO . cptr1
98 | freePtr1 : CPtr -> F1' World
99 | freePtr1 (CP _ p) = toF1 (prim__free p)
102 | ELift1 World f => Resource f CPtr where
103 | cleanup p = lift1 (freePtr1 p)
106 | freePtr : HasIO io => CPtr -> io ()
107 | freePtr = runIO . freePtr1
116 | buf : Bits32 -> F1 World Buf
118 | let b # t := toF1 (prim__newBuf $
cast sz) t
130 | interface FromBuf a where
131 | fromBuf : Buf -> F1 World a
135 | EMBuffer = DPair Nat IOBuffer
139 | EBuffer = DPair Nat IBuffer
143 | fromBuf buf t = buf # t
146 | FromBuf EMBuffer where
147 | fromBuf (B sz buf) t = (
cast sz ** unsafeMBuffer buf)
# t
150 | FromBuf EBuffer where
151 | fromBuf (B sz buf) t = (
cast sz ** unsafeMakeBuffer buf)
# t
154 | FromBuf ByteString where
155 | fromBuf (B sz buf) t = unsafeByteString (cast sz) buf # t
158 | FromBuf String where
160 | let (
n ** ib)
# t := fromBuf {a = EBuffer} buf t
161 | in toString ib 0 n # t
164 | [DecimalString] FromBuf (Maybe Nat) where
166 | let bs # t := fromBuf {a=ByteString} b t
167 | in (parseDecimalNat bs) # t
170 | [HexadecimalString] FromBuf (Maybe Nat) where
172 | let bs # t := fromBuf {a=ByteString} b t
173 | in (parseHexadecimalNat bs) # t
176 | [OctalString] FromBuf (Maybe Nat) where
178 | let bs # t := fromBuf {a=ByteString} b t
179 | in (parseOctalNat bs) # t
182 | [BinaryString] FromBuf (Maybe Nat) where
184 | let bs # t := fromBuf {a=ByteString} b t
185 | in (parseBinaryNat bs) # t
188 | [IntegerString] FromBuf (Maybe Integer) where
190 | let bs # t := fromBuf {a=ByteString} b t
191 | in (parseInteger bs) # t
194 | [DoubleString] FromBuf (Maybe Double) where
196 | let bs # t := fromBuf {a=ByteString} b t
197 | in (parseDouble bs) # t
200 | 0 ECArrayIO : Type -> Type
201 | ECArrayIO t = (
n ** CArrayIO n t)
215 | interface ToBuf a where
216 | unsafeToBuf : a -> Either CPtr ByteString
219 | ToBuf ByteString where
220 | unsafeToBuf = Right
224 | unsafeToBuf = Right . fromString
227 | {n : _} -> ToBuf (IBuffer n) where
228 | unsafeToBuf buf = Right $
unsafeByteString n (unsafeGetBuffer buf)
231 | {n : _} -> ToBuf (MBuffer t n) where
232 | unsafeToBuf buf = Right $
unsafeByteString n (unsafeFromMBuffer buf)
239 | {n : _} -> SizeOf a => ToBuf (CArray t n a) where
241 | Left (CP (cast n * sizeof a) (unsafeUnwrap arr))
244 | SizeOf a => ToBuf (ECArrayIO a) where
245 | unsafeToBuf (
_ ** arr)
= unsafeToBuf arr
248 | {n : _} -> SizeOf a => SetPtr a => ToBuf (Vect n a) where
251 | let sz := cast n * sizeof a
252 | buf # t := ffi (prim__newBuf $
cast sz) t
253 | arr # t := malloc1 a n t
254 | _ # t := writeVect arr vs t
255 | _ # t := ffi (prim__copy_pb (unsafeUnwrap arr) buf sz) t
256 | _ # t := free1 arr t
257 | in Right (unsafeByteString (cast sz) buf) # t
260 | SizeOf a => SetPtr a => ToBuf (List a) where
261 | unsafeToBuf vs = unsafeToBuf (Vect.fromList vs)
268 | [DStruct] Struct f => Deref (f World) where
269 | deref p = pure (swrap p)
272 | record Convert t where
276 | {auto sof : SizeOf source}
277 | {auto derf : Deref source}
278 | convert : source -> F1 World t
282 | (0 f : Type -> Type)
283 | -> {auto iss : Struct f}
284 | -> {auto sof : SizeOf (f World)}
285 | -> (fun : f World -> F1 World t)
287 | convStruct f fun = C (f World) {sof} {derf = DStruct} fun
300 | interface FromPtr a where
301 | fromPtr : CPtr -> F1 World a
308 | SizeOf a => FromPtr (ECArrayIO a) where
309 | fromPtr (CP sz ptr) t =
310 | (
cast (sz `div` sizeof a) ** unsafeWrap ptr)
# t
313 | FromPtr EBuffer where
314 | fromPtr (CP sz32 ptr) t =
315 | let buf # t := toF1 (prim__newBuf $
cast sz32) t
316 | _ # t := toF1 (prim__copy_pb ptr buf sz32) t
317 | in (
cast sz32 ** unsafeMakeBuffer buf)
# t
320 | FromPtr EMBuffer where
321 | fromPtr (CP sz32 ptr) t =
322 | let buf # t := toF1 (prim__newBuf $
cast sz32) t
323 | _ # t := toF1 (prim__copy_pb ptr buf sz32) t
324 | in (
cast sz32 ** unsafeMBuffer buf)
# t
327 | FromPtr ByteString where
329 | let (
n ** ib)
# t := fromPtr {a = EBuffer} cp t
330 | in BS n (fromIBuffer ib) # t
333 | FromPtr String where
335 | let (
n ** ib)
# t := fromPtr {a = EBuffer} cp t
336 | in toString ib 0 n # t
339 | Convert t => FromPtr (List t) where
340 | fromPtr @{C src conv} cp t =
341 | let (
n ** arr)
# t := fromPtr {a = ECArrayIO src} cp t
342 | in values [] arr conv n t
345 | SizeOf a => Deref a => FromPtr (List a) where
347 | let (
n ** arr)
# t := fromPtr {a = ECArrayIO a} cp t
348 | in values [] arr (#) n t
352 | fromBuf (B sz buf) t =
353 | let p := prim__malloc sz
354 | _ # t := toF1 (prim__copy_bp buf p sz) t
358 | SizeOf a => FromBuf (ECArrayIO a) where
359 | fromBuf b t = let cp # t := fromBuf b t in fromPtr cp t
362 | viaPtrFromBuf : FromPtr r => Buf -> F1 World r
363 | viaPtrFromBuf b t =
364 | let cp # t := fromBuf b t
365 | r # t := fromPtr cp t
366 | _ # t := freePtr1 cp t
370 | Convert t => FromBuf (List t) where
371 | fromBuf = viaPtrFromBuf