Files
managed-git/Git/Stream.fs
2022-09-12 14:51:32 +01:00

57 lines
1.6 KiB
Forth

namespace Git.Internals
open System.IO
[<RequireQualifiedAccess>]
module internal Stream =
/// Consume the stream until and including the first instance of `stopAt`.
/// Return None instead if the stream is already used up; throw if we hit the end of the stream
/// before hitting `stopAt`.
let consumeTo (b : Stream) (stopAt : byte) : byte array option =
let rec consumeTo () : byte seq =
seq {
let b = b.ReadByte ()
if b < 0 then
failwithf "Stream ended in the middle while consuming to '%i'." stopAt
if b <> int stopAt then
yield byte b
yield! consumeTo ()
}
// Read the first one to see if we can
let firstByte = b.ReadByte ()
if firstByte < 0 then
None
else
let firstByte = byte firstByte
if firstByte = stopAt then
Array.empty |> Some
else
seq {
yield firstByte
yield! consumeTo ()
}
|> Seq.toArray
|> Some
/// Consume the first n bytes of the stream. Throw if the stream runs out first.
let consume (b : Stream) (n : int) : byte array =
let output = Array.zeroCreate<byte> n
let total = b.Read (output, 0, n)
if total <> n then
failwithf "Reached the end of the stream while consuming %i bytes" n
output
let consumeToEnd (b : Stream) : byte array =
use newMs = new MemoryStream ()
b.CopyTo newMs
newMs.ToArray ()