open System open System.Collections open System.Collections.Generic open System.Diagnostics.Contracts open System.IO open System.Runtime.Serialization open System.Runtime.Serialization.Formatters.Binary open System.Text /// Initializes a new instance of the SeqStream class. /// type SeqStream(data:seq) = inherit Stream() do Contract.Requires(data <> null) let d = data.GetEnumerator() override this.CanRead = true override this.CanSeek = false override this.CanWrite = false override this.Flush() = () override this.Length = data |> Seq.length |> int64 override this.Position with get() = raise (NotSupportedException()) and set(v) = raise (NotSupportedException()) override this.Seek(offset, origin) = raise (NotSupportedException()) override this.SetLength(value) = raise (NotSupportedException()) override this.Write(buffer, offset, count) = raise (NotSupportedException()) override this.Dispose(disposing) = d.Dispose() base.Dispose(disposing) override this.Read(buffer, offset, count) = Contract.Requires(buffer <> null) Contract.Requires(offset >= 0) Contract.Requires(count > 0) Contract.Requires(offset + count <= buffer.Length) let rec loop bytesRead = if d.MoveNext() && bytesRead < count then buffer.[bytesRead + offset] <- d.Current loop (bytesRead + 1) else bytesRead loop 0 /// Returns the SeqStream as a UTF8 encoded string. override this.ToString() = Encoding.UTF8.GetString(data |> Seq.toArray) /// An empty SeqStream. static member Empty = new SeqStream(Seq.empty) /// Converts a string into a SeqStream. static member FromString(s:string) = new SeqStream(Encoding.UTF8.GetBytes(s)) /// Converts a stream into a SeqStream. static member FromStream(stream:Stream, ?bufferSize) = let bufferSize = defaultArg bufferSize 1024 Contract.Requires(stream <> null) Contract.Requires(bufferSize > 0) let buffer = Array.zeroCreate bufferSize let count = ref 0 count := stream.Read(buffer, 0, buffer.Length) let bytes = seq { while !count > 0 do for i in [0..(!count-1)] do yield buffer.[i] count := stream.Read(buffer, 0, buffer.Length) } new SeqStream(bytes) /// Converts a FileInfo into a SeqStream. static member FromFileInfo(file:FileInfo) = Contract.Requires(file <> null) use stream = file.OpenRead() SeqStream.FromStream(stream, int stream.Length) /// Converts an object to a SeqStream. static member FromObject(ob) = let formatter = BinaryFormatter() use stream = new MemoryStream() try formatter.Serialize(stream, ob) SeqStream.FromStream(stream) with :? SerializationException as e -> SeqStream.Empty