/// <summary>
        /// Reads a sequence of bytes from the current stream and advances the position
        /// within the stream by the number of bytes read.
        /// </summary>
        /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source.</param>
        /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
        /// <param name="count">The maximum number of bytes to be read from the current stream.</param>
        /// <returns>The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (TheIStream != null)
            {
                if (offset != 0)
                {
                    throw new NotSupportedException("Only a zero offset is supported.");
                }

                var bytesRead = 0;
                var br        = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
                Marshal.WriteInt32(br, 0);

                // Include try catch for c++ eh exceptions. are they the same as comexceptions?
                TheIStream.Read(buffer, count, br);
                bytesRead = Marshal.ReadInt32(br);

                Marshal.FreeHGlobal(br);

                return(bytesRead);
            }
            else
            {
                return(TheStream.Read(buffer, offset, count));
            }
        }
        /// <summary>
        /// Changes the seek pointer to a new location relative to the beginning
        ///of the stream, the end of the stream, or the current seek pointer
        /// </summary>
        /// <param name="dlibMove">
        /// The displacement to be added to the location indicated by the dwOrigin parameter.
        /// If dwOrigin is STREAM_SEEK_SET, this is interpreted as an unsigned value rather than a signed value.
        /// </param>
        /// <param name="dwOrigin">
        /// The origin for the displacement specified in dlibMove.
        /// The origin can be the beginning of the file (STREAM_SEEK_SET), the current seek pointer (STREAM_SEEK_CUR), or the end of the file (STREAM_SEEK_END).
        /// </param>
        /// <param name="plibNewPosition">
        /// The location where this method writes the value of the new seek pointer from the beginning of the stream.
        /// It can be set to IntPtr.Zero. In this case, this method does not provide the new seek pointer.
        /// </param>
        /// <typeparam name="pcbRead">Native UInt64</typeparam>
        /// <returns>
        /// Returns in <paramref name="plibNewPosition"/> the location where this method writes the value of the new seek pointer from the beginning of the stream.
        /// </returns>
        ///<exception cref="IOException">An I/O error occurs.</exception>
        ///<exception cref="NotSupportedException">The stream does not support reading.</exception>
        ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
        public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
        {
            if (TheStream != null)
            {
                // The enum values of SeekOrigin match the enum values of
                // STREAM_SEEK, so we can just cast the dwOrigin to a SeekOrigin

                if (plibNewPosition == IntPtr.Zero)
                {
                    // User isn't interested in new position
                    TheStream.Seek(dlibMove, (SeekOrigin)dwOrigin);
                }
                else
                {
                    var origin = (SeekOrigin)dwOrigin;
                    if (origin != SeekOrigin.Begin &&
                        origin != SeekOrigin.Current &&
                        origin != SeekOrigin.End)
                    {
                        origin = SeekOrigin.Begin;
                    }
                    Marshal.WriteInt64(plibNewPosition, TheStream.Seek(dlibMove, origin));
                }
            }
            else
            {
                TheIStream.Seek(dlibMove, dwOrigin, plibNewPosition);
            }
        }
 /// <summary>
 /// Sets the length of the current stream.
 /// </summary>
 /// <param name="value">The desired length of the current stream in bytes.</param>
 public override void SetLength(long value)
 {
     if (TheIStream != null)
     {
         TheIStream.SetSize(value);
     }
     else
     {
         TheStream.SetLength(value);
     }
 }
 /// <summary>
 /// Clears all buffers for this stream and causes any buffered data to be written
 /// to the underlying device.
 /// </summary>
 public override void Flush()
 {
     if (TheIStream != null)
     {
         TheIStream.Commit(0 /*STGC_DEFAULT*/);
     }
     else
     {
         TheStream.Flush();
     }
 }
 /// <summary>
 /// Changes the size of the stream object.
 /// </summary>
 /// <param name="libNewSize">Specifies the new size of the stream as a number of bytes.</param>
 ///<exception cref="IOException">An I/O error occurs.</exception>
 ///<exception cref="NotSupportedException">The stream does not support reading.</exception>
 ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
 public void SetSize(long libNewSize)
 {
     if (TheStream != null)
     {
         // Sets the length of the current stream.
         TheStream.SetLength(libNewSize);
     }
     else
     {
         TheIStream.SetSize(libNewSize);
     }
 }
 /// <summary>
 /// Closes the current stream and releases any resources
 /// (such as the Stream) associated with the current IStream.
 /// </summary>
 /// <remarks>
 /// This method is not a member in IStream.
 /// </remarks>
 public override void Close()
 {
     if (TheStream != null)
     {
         TheStream.Close();
     }
     else
     {
         TheIStream.Commit(0 /*STGC_DEFAULT*/);
         //                Marshal.ReleaseComObject(TheIStream);    // Investigate this because we cannot release an IStream to the stash file
     }
     GC.SuppressFinalize(this);
 }
 /// <summary>
 /// Ensures that any changes made to an stream object that is open in transacted
 /// mode are reflected in the parent storage.
 /// </summary>
 /// <remarks>
 /// The <paramref name="grfCommitFlags"/> parameter is not used and this method only does Stream.Flush()
 /// </remarks>
 /// <param name="grfCommitFlags">Controls how the changes for the stream object are committed.
 /// See the STGC enumeration for a definition of these values.</param>
 ///<exception cref="IOException">An I/O error occurs.</exception>
 public void Commit(int grfCommitFlags)
 {
     // Clears all buffers for this stream and causes any buffered data to be written
     // to the underlying device.
     if (TheStream != null)
     {
         TheStream.Flush();
     }
     else
     {
         TheIStream.Commit(grfCommitFlags);
     }
 }
        /// <summary>
        /// Copies a specified number of bytes from the current seek pointer in the stream
        /// to the current seek pointer in another stream.
        /// </summary>
        /// <param name="pstm">
        /// The destination stream. The pstm stream  can be a new stream or a clone of the source stream.
        /// </param>
        /// <param name="cb">
        /// The number of bytes to copy from the source stream.
        /// </param>
        /// <param name="pcbRead">
        /// The actual number of bytes read from the source.
        /// It can be set to IntPtr.Zero.
        /// In this case, this method does not provide the actual number of bytes read.
        /// </param>
        /// <typeparam name="pcbRead">Native UInt64</typeparam>
        /// <param name="pcbWritten">
        /// The actual number of bytes written to the destination.
        /// It can be set this to IntPtr.Zero.
        /// In this case, this method does not provide the actual number of bytes written.
        /// </param>
        /// <typeparam name="pcbWritten">Native UInt64</typeparam>
        /// <returns>
        /// The actual number of bytes read (<paramref name="pcbRead"/>) and written (<paramref name="pcbWritten"/>) from the source.
        /// </returns>
        ///<exception cref="ArgumentException">The sum of offset and count is larger than the buffer length.</exception>
        ///<exception cref="ArgumentNullException">buffer is a null reference.</exception>
        ///<exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
        ///<exception cref="IOException">An I/O error occurs.</exception>
        ///<exception cref="NotSupportedException">The stream does not support reading.</exception>
        ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
        public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
        {
            if (TheStream != null)
            {
                var  sourceBytes         = new byte[cb];
                var  currentBytesRead    = 0;
                long totalBytesRead      = 0;
                var  currentBytesWritten = 0;
                long totalBytesWritten   = 0;

                var bw = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
                Marshal.WriteInt32(bw, 0);

                while (totalBytesWritten < cb)
                {
                    currentBytesRead = TheStream.Read(sourceBytes, 0, (int)(cb - totalBytesWritten));

                    // Has the end of the stream been reached?
                    if (currentBytesRead == 0)
                    {
                        break;
                    }

                    totalBytesRead += currentBytesRead;

                    pstm.Write(sourceBytes, currentBytesRead, bw);
                    currentBytesWritten = Marshal.ReadInt32(bw);
                    if (currentBytesWritten != currentBytesRead)
                    {
                        Debug.WriteLine("ERROR!: The IStream Write is not writing all the bytes needed!");
                    }
                    totalBytesWritten += currentBytesWritten;
                }

                Marshal.FreeHGlobal(bw);

                if (pcbRead != IntPtr.Zero)
                {
                    Marshal.WriteInt64(pcbRead, totalBytesRead);
                }
                if (pcbWritten != IntPtr.Zero)
                {
                    Marshal.WriteInt64(pcbWritten, totalBytesWritten);
                }
            }
            else
            {
                TheIStream.CopyTo(pstm, cb, pcbRead, pcbWritten);
            }
        }
        // Writes a sequence of bytes to the current stream and advances the
        // current position within this stream by the number of bytes written
        /// <summary>
        /// Writes a sequence of bytes to the current stream and advances the current position
        /// within this stream by the number of bytes written.
        /// </summary>
        /// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
        /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
        /// <param name="count">The number of bytes to be written to the current stream.</param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (TheIStream != null)
            {
                if (offset != 0)
                {
                    throw new NotSupportedException("Only a zero offset is supported.");
                }

                // Pass "null" for the last parameter since we don't use the value
                TheIStream.Write(buffer, count, IntPtr.Zero);
            }
            else
            {
                TheStream.Write(buffer, offset, count);
            }
        }
Esempio n. 10
0
 /// <summary>
 /// Reads a specified number of bytes from the stream object
 /// into memory starting at the current seek pointer.
 /// </summary>
 /// <param name="pv">The buffer which the stream data is read into.</param>
 /// <param name="cb">The number of bytes of data to read from the stream object.</param>
 /// <param name="pcbRead">
 /// A pointer to a ULONG variable that receives the actual number of bytes read from the stream object.
 /// It can be set to IntPtr.Zero.
 /// In this case, this method does not return the number of bytes read.
 /// </param>
 /// <typeparam name="pcbRead">Native UInt32</typeparam>
 /// <returns>
 /// The actual number of bytes read (<paramref name="pcbRead"/>) from the source.
 /// </returns>
 ///<exception cref="ArgumentException">The sum of offset and count is larger than the buffer length.</exception>
 ///<exception cref="ArgumentNullException">buffer is a null reference.</exception>
 ///<exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
 ///<exception cref="IOException">An I/O error occurs.</exception>
 ///<exception cref="NotSupportedException">The stream does not support reading.</exception>
 ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
 public void Read(byte[] pv, int cb, IntPtr pcbRead)
 {
     if (TheStream != null)
     {
         if (pcbRead == IntPtr.Zero)
         {
             // User isn't interested in how many bytes were read
             TheStream.Read(pv, 0, cb);
         }
         else
         {
             Marshal.WriteInt32(pcbRead, TheStream.Read(pv, 0, cb));
         }
     }
     else
     {
         TheIStream.Read(pv, cb, pcbRead);
     }
 }
Esempio n. 11
0
 /// <summary>
 /// Writes a specified number of bytes into the stream object
 ///starting at the current seek pointer.
 /// </summary>
 /// <param name="pv">The buffer that contains the data that is to be written to the stream.
 /// A valid buffer must be provided for this parameter even when cb is zero.</param>
 /// <param name="cb">The number of bytes of data to attempt to write into the stream. This value can be zero.</param>
 /// <param name="pcbWritten">
 /// A variable where this method writes the actual number of bytes written to the stream object.
 /// The caller can set this to IntPtr.Zero, in which case this method does not provide the actual number of bytes written.
 /// </param>
 /// <typeparam name="pcbWritten">Native UInt32</typeparam>
 /// <returns>
 /// The actual number of bytes written (<paramref name="pcbWritten"/>).
 /// </returns>
 ///<exception cref="ArgumentException">The sum of offset and count is larger than the buffer length.</exception>
 ///<exception cref="ArgumentNullException">buffer is a null reference.</exception>
 ///<exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
 ///<exception cref="IOException">An I/O error occurs.</exception>
 ///<exception cref="NotSupportedException">The IO.Stream does not support reading.</exception>
 ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
 public void Write(byte[] pv, int cb, IntPtr pcbWritten)
 {
     if (TheStream != null)
     {
         if (pcbWritten == IntPtr.Zero)
         {
             // User isn't interested in how many bytes were written
             TheStream.Write(pv, 0, cb);
         }
         else
         {
             var currentPosition = TheStream.Position;
             TheStream.Write(pv, 0, cb);
             Marshal.WriteInt32(pcbWritten, (int)(TheStream.Position - currentPosition));
         }
     }
     else
     {
         TheIStream.Write(pv, cb, pcbWritten);
     }
 }
Esempio n. 12
0
        /// <summary>
        /// Sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A byte offset relative to the origin parameter.</param>
        /// <param name="origin">A value of type SeekOrigin indicating the reference point used to obtain the new position.</param>
        /// <returns>The new position within the current stream.</returns>
        public override long Seek(long offset, System.IO.SeekOrigin origin)
        {
            if (TheIStream != null)
            {
                long position = 0;
                var  pos      = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(long)));
                Marshal.WriteInt64(pos, 0);

                // The enum values of SeekOrigin match the enum values of
                // STREAM_SEEK, so we can just cast the origin to an integer.
                TheIStream.Seek(offset, (int)origin, pos);
                position = Marshal.ReadInt64(pos);

                Marshal.FreeHGlobal(pos);

                return(position);
            }
            else
            {
                return(TheStream.Seek(offset, origin));
            }
        }