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