Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This class wraps an IStream interface into a System.IO.Stream class. Since this code is for a classifier, there's no need to write to the provided stream since the pipeline only provides read-only streams to classifiers. Thus, the methods that modify the stream are not implemented.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace Microsoft.Samples.Fsrm.Classifiers
{
public class StreamWrapper : Stream
{
private IStream m_stream;
private void CheckDisposed()
{
if (m_stream == null)
{
throw new ObjectDisposedException("StreamWrapper");
}
}
protected override void Dispose(bool disposing)
{
if (m_stream != null)
{
Marshal.ReleaseComObject(m_stream);
m_stream = null;
}
}
public StreamWrapper(IStream stream)
{
if (stream == null)
{
throw new ArgumentNullException();
}
m_stream = stream;
}
public override bool CanRead
{
get
{
return true;
}
}
public override bool CanSeek
{
get
{
return true;
}
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void Flush()
{
throw new NotImplementedException();
}
public override long Length
{
get
{
CheckDisposed();
System.Runtime.InteropServices.ComTypes.STATSTG stat;
m_stream.Stat(out stat, 1); //STATFLAG_NONAME
return stat.cbSize;
}
}
public override long Position
{
get
{
return Seek(0, SeekOrigin.Current);
}
set
{
Seek(value, SeekOrigin.Begin);
}
}
public override int Read(byte[] buffer, int offset, int count)
{
CheckDisposed();
if (offset < 0 || count < 0 || offset + count > buffer.Length)
{
throw new ArgumentOutOfRangeException();
}
byte[] localBuffer = buffer;
if (offset > 0)
{
localBuffer = new byte[count];
}
IntPtr bytesReadPtr = Marshal.AllocCoTaskMem(sizeof(int));
try
{
m_stream.Read(localBuffer, count, bytesReadPtr);
int bytesRead = Marshal.ReadInt32(bytesReadPtr);
if (offset > 0)
{
Array.Copy(localBuffer, 0, buffer, offset, bytesRead);
}
return bytesRead;
}
finally
{
Marshal.FreeCoTaskMem(bytesReadPtr);
}
}
public override long Seek(long offset, SeekOrigin origin)
{
CheckDisposed();
int dwOrigin;
switch (origin)
{
case SeekOrigin.Begin:
dwOrigin = 0; // STREAM_SEEK_SET
break;
case SeekOrigin.Current:
dwOrigin = 1; // STREAM_SEEK_CUR
break;
case SeekOrigin.End:
dwOrigin = 2; // STREAM_SEEK_END
break;
default:
throw new ArgumentOutOfRangeException();
}
IntPtr posPtr = Marshal.AllocCoTaskMem(sizeof(long));
try
{
m_stream.Seek(offset, dwOrigin, posPtr);
return Marshal.ReadInt64(posPtr);
}
finally
{
Marshal.FreeCoTaskMem(posPtr);
}
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}
}