﻿// Decompiled with JetBrains decompiler
// Type: System.Data.SqlTypes.StreamOnSqlBytes
// Assembly: System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: A0A8E655-5215-4802-816D-C9E5EBD7DA5D
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll

using System;
using System.Data.Common;
using System.IO;

namespace System.Data.SqlTypes
{
  internal sealed class StreamOnSqlBytes : Stream
  {
    private SqlBytes m_sb;
    private long m_lPosition;

    public override bool CanRead
    {
      get
      {
        if (this.m_sb != null)
          return !this.m_sb.IsNull;
        return false;
      }
    }

    public override bool CanSeek
    {
      get
      {
        return this.m_sb != null;
      }
    }

    public override bool CanWrite
    {
      get
      {
        if (this.m_sb == null)
          return false;
        if (this.m_sb.IsNull)
          return this.m_sb.m_rgbBuf != null;
        return true;
      }
    }

    public override long Length
    {
      get
      {
        this.CheckIfStreamClosed("get_Length");
        return this.m_sb.Length;
      }
    }

    public override long Position
    {
      get
      {
        this.CheckIfStreamClosed("get_Position");
        return this.m_lPosition;
      }
      set
      {
        this.CheckIfStreamClosed("set_Position");
        if (value < 0L || value > this.m_sb.Length)
          throw new ArgumentOutOfRangeException("value");
        this.m_lPosition = value;
      }
    }

    internal StreamOnSqlBytes(SqlBytes sb)
    {
      this.m_sb = sb;
      this.m_lPosition = 0L;
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
      this.CheckIfStreamClosed("Seek");
      switch (origin)
      {
        case SeekOrigin.Begin:
          if (offset < 0L || offset > this.m_sb.Length)
            throw new ArgumentOutOfRangeException("offset");
          this.m_lPosition = offset;
          break;
        case SeekOrigin.Current:
          long num1 = this.m_lPosition + offset;
          if (num1 < 0L || num1 > this.m_sb.Length)
            throw new ArgumentOutOfRangeException("offset");
          this.m_lPosition = num1;
          break;
        case SeekOrigin.End:
          long num2 = this.m_sb.Length + offset;
          if (num2 < 0L || num2 > this.m_sb.Length)
            throw new ArgumentOutOfRangeException("offset");
          this.m_lPosition = num2;
          break;
        default:
          throw ADP.InvalidSeekOrigin("offset");
      }
      return this.m_lPosition;
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
      this.CheckIfStreamClosed("Read");
      if (buffer == null)
        throw new ArgumentNullException("buffer");
      if (offset < 0 || offset > buffer.Length)
        throw new ArgumentOutOfRangeException("offset");
      if (count < 0 || count > buffer.Length - offset)
        throw new ArgumentOutOfRangeException("count");
      int num = (int) this.m_sb.Read(this.m_lPosition, buffer, offset, count);
      this.m_lPosition += (long) num;
      return num;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
      this.CheckIfStreamClosed("Write");
      if (buffer == null)
        throw new ArgumentNullException("buffer");
      if (offset < 0 || offset > buffer.Length)
        throw new ArgumentOutOfRangeException("offset");
      if (count < 0 || count > buffer.Length - offset)
        throw new ArgumentOutOfRangeException("count");
      this.m_sb.Write(this.m_lPosition, buffer, offset, count);
      this.m_lPosition += (long) count;
    }

    public override int ReadByte()
    {
      this.CheckIfStreamClosed("ReadByte");
      if (this.m_lPosition >= this.m_sb.Length)
        return -1;
      int num = (int) this.m_sb[this.m_lPosition];
      ++this.m_lPosition;
      return num;
    }

    public override void WriteByte(byte value)
    {
      this.CheckIfStreamClosed("WriteByte");
      this.m_sb[this.m_lPosition] = value;
      ++this.m_lPosition;
    }

    public override void SetLength(long value)
    {
      this.CheckIfStreamClosed("SetLength");
      this.m_sb.SetLength(value);
      if (this.m_lPosition <= value)
        return;
      this.m_lPosition = value;
    }

    public override void Flush()
    {
      if (!this.m_sb.FStream())
        return;
      this.m_sb.m_stream.Flush();
    }

    protected override void Dispose(bool disposing)
    {
      try
      {
        this.m_sb = (SqlBytes) null;
      }
      finally
      {
        base.Dispose(disposing);
      }
    }

    private bool FClosed()
    {
      return this.m_sb == null;
    }

    private void CheckIfStreamClosed(string methodname)
    {
      if (this.FClosed())
        throw ADP.StreamClosed(methodname);
    }
  }
}
