// Decompiled with JetBrains decompiler
// Type: SevenZip.Compression.LZ.OutWindow
// Assembly: actmp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 0EE5924A-FEF0-47DE-B492-05CBFEE65091
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00001-msil\Trojan.MSIL.Crypt.hmzi-0f975d7cb826475f5ef4738179c8294d30c9ebe6d262042d9e21b2c535131135.exe

using System;
using System.IO;

namespace SevenZip.Compression.LZ
{
  public class OutWindow
  {
    private byte[] _buffer;
    private uint _pos;
    private uint _windowSize;
    private uint _streamPos;
    private Stream _stream;

    public void Create(uint windowSize)
    {
      if ((int) this._windowSize != (int) windowSize)
        this._buffer = new byte[(IntPtr) windowSize];
      this._windowSize = windowSize;
      this._pos = 0U;
      this._streamPos = 0U;
    }

    public void Init(Stream stream, bool solid)
    {
      this.ReleaseStream();
      this._stream = stream;
      if (solid)
        return;
      this._streamPos = 0U;
      this._pos = 0U;
    }

    public void Init(Stream stream) => this.Init(stream, false);

    public void ReleaseStream()
    {
      this.Flush();
      this._stream = (Stream) null;
    }

    public void Flush()
    {
      uint count = this._pos - this._streamPos;
      if (count == 0U)
        return;
      this._stream.Write(this._buffer, (int) this._streamPos, (int) count);
      if (this._pos >= this._windowSize)
        this._pos = 0U;
      this._streamPos = this._pos;
    }

    public void CopyBlock(uint distance, uint len)
    {
      uint num = (uint) ((int) this._pos - (int) distance - 1);
      if (num >= this._windowSize)
        num += this._windowSize;
      for (; len > 0U; --len)
      {
        if (num >= this._windowSize)
          num = 0U;
        this._buffer[(IntPtr) this._pos++] = this._buffer[(IntPtr) num++];
        if (this._pos >= this._windowSize)
          this.Flush();
      }
    }

    public void PutByte(byte b)
    {
      this._buffer[(IntPtr) this._pos++] = b;
      if (this._pos < this._windowSize)
        return;
      this.Flush();
    }

    public byte GetByte(uint distance)
    {
      uint index = (uint) ((int) this._pos - (int) distance - 1);
      if (index >= this._windowSize)
        index += this._windowSize;
      return this._buffer[(IntPtr) index];
    }
  }
}
