Example #1
0
        /// <summary>
        /// Compress a stream with ZLib
        /// </summary>
        /// <param name="snipStreamWrapper">A stream wrapper object</param>
        /// <param name="compressLevel">Compression level of stream.</param>
        public static void Compress(SnipStreamWrapper snipStreamWrapper, CompressLevel compressLevel)
        {
            var numBytesAddressing = snipStreamWrapper.OutputBufferLength;

            ZLibWrapper.CopyByteArrayToInputBuffer(snipStreamWrapper.OutputBuffer, 0,
                                                   snipStreamWrapper.OutputBufferLength);

            if (_deflaterBest == null)
            {
                _deflaterBest = new Deflater(CompressLevel.Best);
                _deflaterBest.DataAvailable += ZLibWrapper.WriteInOutputBuffer;
            }

            if (_deflaterNone == null)
            {
                _deflaterNone = new Deflater(CompressLevel.None);
                _deflaterNone.DataAvailable += ZLibWrapper.WriteInOutputBuffer;
            }

            if (_deflaterFastest == null)
            {
                _deflaterFastest = new Deflater(CompressLevel.Fastest);
                _deflaterFastest.DataAvailable += ZLibWrapper.WriteInOutputBuffer;
            }

            if (_deflaterDefault == null)
            {
                _deflaterDefault = new Deflater(CompressLevel.Default);
                _deflaterDefault.DataAvailable += ZLibWrapper.WriteInOutputBuffer;
            }

            try
            {
                while (numBytesAddressing > 0u)
                {
                    uint numBytes = Math.Min(numBytesAddressing, 8192u); //8192u); 65536u

                    if (compressLevel == CompressLevel.None)
                        _deflaterNone.Add(ZLibWrapper.ReadBytes((int) numBytes, ZLibBufferType.InputBuffer));

                    if (compressLevel == CompressLevel.Best)
                        _deflaterBest.Add(ZLibWrapper.ReadBytes((int) numBytes, ZLibBufferType.InputBuffer));

                    if (compressLevel == CompressLevel.Default)
                        _deflaterDefault.Add(ZLibWrapper.ReadBytes((int) numBytes, ZLibBufferType.InputBuffer));

                    if (compressLevel == CompressLevel.Fastest)
                        _deflaterFastest.Add(ZLibWrapper.ReadBytes((int) numBytes, ZLibBufferType.InputBuffer));

                    numBytesAddressing -= numBytes;
                }

                string deflateErrorMsg = string.Empty;
                if (compressLevel == CompressLevel.None)
                    deflateErrorMsg = _deflaterNone._ztream.msg;

                if (compressLevel == CompressLevel.Best)
                    deflateErrorMsg = _deflaterBest._ztream.msg;

                if (compressLevel == CompressLevel.Default)
                    deflateErrorMsg = _deflaterDefault._ztream.msg;

                if (compressLevel == CompressLevel.Fastest)
                    deflateErrorMsg = _deflaterFastest._ztream.msg;

                if (!string.IsNullOrWhiteSpace(deflateErrorMsg))
                    MessageBox.Show(string.Format("ZLib.Compress: {0}", deflateErrorMsg),
                                    TranslateUI.TranslateUiGlobalization.ResManager.GetString("ZLib_Error"),
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);

                if (compressLevel == CompressLevel.None)
                    _deflaterNone.Finish(); // flush zlib buffer

                if (compressLevel == CompressLevel.Best)
                    _deflaterBest.Finish(); // flush zlib buffer

                if (compressLevel == CompressLevel.Default)
                    _deflaterDefault.Finish(); // flush zlib buffer

                if (compressLevel == CompressLevel.Fastest)
                    _deflaterFastest.Finish(); // flush zlib buffer

                ZLibWrapper.Position(0, ZLibBufferType.OutputBuffer);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    string.Format(TranslateUI.TranslateUiGlobalization.ResManager.GetString(name: "MSG_ErrorWithNewLine"), arg0: ex),
                    TranslateUI.TranslateUiGlobalization.ResManager.GetString(name: "ZLib_Compress"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
            finally
            {
                if (ZLibWrapper.OutputBufferLength == 0)
                {
                    MessageBox.Show(
                        TranslateUI.TranslateUiGlobalization.ResManager.GetString(name: "ZLib_OutputBufferEmpty"),
                        TranslateUI.TranslateUiGlobalization.ResManager.GetString(name: "ZLib_Compress"),
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
            }
        }
Example #2
0
 //internal abstract void SaveData(BinaryWriter writer);
 internal abstract void SaveData(SnipStreamWrapper snipStreamWrapper);
Example #3
0
        internal Record(string name, uint dataSizeParam, SnipStreamWrapper snipStreamWrapper, bool oblivion)  //internal Record(string name, uint dataSize, BinaryReader recordReader, bool oblivion) 
        {
            bool compressed = false;
            uint amountRead = 0;
            uint realSize = 0;

            //MemoryStream stream = null;
            //BinaryReader dataReader = null;
            SubRecord record = null;
            //long ws;

            try
            {
                this.dataSize = dataSizeParam;

                this.SubRecords = new AdvancedList<SubRecord>(1) {AllowSorting = false};

                //if (snipStreamWrapper.SnipStream.Position >= 1330432)
                //    Name = name;

                Name = name;
                RecordsTace.AddRecordToRecordsList(Name);
                this.Flags1 = snipStreamWrapper.ReadUInt32(); //recordReader.ReadUInt32();
                this.FormID = snipStreamWrapper.ReadUInt32(); //recordReader.ReadUInt32();
                this.Flags2 = snipStreamWrapper.ReadUInt32(); //recordReader.ReadUInt32();
                if (!oblivion)
                {
                    this.Flags3 = snipStreamWrapper.ReadUInt32(); //recordReader.ReadUInt32();
                }

                //if (this.FormID == 496431)
                //    Name = name;

                compressed = (this.Flags1 & 0x00040000) != 0;
                amountRead = 0;
                realSize = dataSizeParam;

                if (!compressed)
                    realSize = dataSizeParam;

                if (compressed)
                {
                    realSize = snipStreamWrapper.ReadUInt32(); // recordReader.ReadUInt32();
                    // snipStreamWrapper.JumpTo(-4,SeekOrigin.Current);
                    //if (realSize > 0)
                    dataSizeParam -= 4;
                    RecordsTace.AddRecordToCompressedRecordsList(Name);
                }

#if DEBUGCOMPRESSREALSIZE

                if (compressed & realSize == 0)
                {
                    Clipboard.SetText(name + " - " + this.FormID.ToString(CultureInfo.InvariantCulture));
                }
#endif

                //using (var stream = new MemoryStream(recordReader.ReadBytes((int) dataSize)))
                //{
                //using (var dataReader = compressed ? ZLib.Decompress(stream, (int) realSize) : new BinaryReader(stream))
                //{.
                try
                {
                    //if (dataSize == 0)
                    //    throw new TESParserException("Record.Record: ZLib inflate error. Output buffer is empty.");

                    if (dataSizeParam > 0) //dawnguard.esm at position 6.812.369 at a dataSize == 0 - Record=NAVM
                    {
                        ZLibWrapper.CopyStreamToInputBuffer(snipStreamWrapper.SnipStream, dataSizeParam);
                        //stream = new MemoryStream(recordReader.ReadBytes((int) dataSize));
                        //dataReader = compressed ? ZLib.Decompress(stream, out compressLevel, (int)realSize) : new BinaryReader(stream);
                        if (compressed & realSize > 0)
                        {
                            //Clipboard.SetText(Name + realSize.ToString(CultureInfo.InvariantCulture));
                            ZLib.Decompress(compressLevel: out compressLevel, expectedSize: (int) realSize);
                            //Array.Copy();
                        }
                        else
                        {
                            ZLibWrapper.CopyInputBufferToOutputBuffer(dataSizeParam);
                        }
                    }
                    else
                    {
                        ZLibWrapper.ResetBufferSizeAndPosition();
                    }
                }
                catch (Exception ex)
                {
                    throw new TESParserException("Record.Record: ZLib error" + Environment.NewLine +
                                                 "Message: " + ex.Message +
                                                 Environment.NewLine +
                                                 "StackTrace: " + ex.StackTrace);
                }

                if (compressed & dataSizeParam > 0) //dawnguard.esm at position 6.812.369 at a dataSize == 0 - Record=NAVM
                    if (ZLibWrapper.OutputBufferLength <= 0) //if (dataReader == null)
                    {
                        throw new TESParserException("Record.Record: ZLib inflate error. Output buffer is empty.");
                    }

                    while (ZLibWrapper.OutputBufferPosition < ZLibWrapper.OutputBufferLength)
                        //while (dataReader.BaseStream.Position < dataReader.BaseStream.Length)
                    {
                        var type = "XXXX";
                        uint size = 0;
                        if (realSize == 0) //compressed & 
                        {
                            type = "????"; //ReadRecName(ZLibWrapper.Read4Bytes());
                            size = dataSizeParam;
                            //realSize = dataSizeParam;
                            //this.dataSize = dataSizeParam;
                        }
                        else
                        {
                            type = ReadRecName(ZLibWrapper.Read4Bytes()); //var type = ReadRecName(dataReader);
                            
                            if (type == "XXXX")
                            {
                                ZLibWrapper.ReadUInt16(); //dataReader.ReadUInt16();
                                size = ZLibWrapper.ReadUInt32(); //dataReader.ReadUInt32();
                                type = ReadRecName(ZLibWrapper.Read4Bytes()); //ReadRecName(dataReader);
                                ZLibWrapper.ReadUInt16(); //dataReader.ReadUInt16();
                            }
                            else
                            {
                                size = ZLibWrapper.ReadUInt16(); //dataReader.ReadUInt16();
                            }
                        }
                        record = new SubRecord(this, type, snipStreamWrapper, size);
                        //record = new SubRecord(this, type, dataReader, size); //var record = new SubRecord(this, type, dataReader, size);
                        this.SubRecords.Add(record);
                        amountRead += (uint) record.Size2;
                    }

                //} //using (var dataReader = compressed ? ZLib.Decompress(stream, (int) realSize) : new BinaryReader(stream))
                //if (dataReader != null)
                //{
                //    dataReader.Close();
                //    dataReader.Dispose();
                //    dataReader = null;
                //}

                    if ((compressed & realSize != 0) | (!compressed))
                        if (amountRead > realSize)
                        {
                            Debug.Print(
                                " * ERROR: SUB-RECORD {0} DATA DOESN'T MATCH THE SIZE SPECIFIED IN THE HEADER: DATA-SIZE={1} REAL-SIZE={2} AMOUNT-READ={3}",
                                name, dataSizeParam, realSize, amountRead);
                            throw new TESParserException(
                                string.Format(
                                    "Subrecord block did not match the size specified in the record header: ExpectedSize={0} ReadSize={1} DataSize={2}",
                                    realSize, amountRead, dataSizeParam));
                        }


                this.descNameOverride = this.DefaultDescriptiveName;
                this.UpdateShortDescription();

                // br.BaseStream.Position+=Size;

                //} //using (var stream = new MemoryStream(recordReader.ReadBytes((int) dataSize)))
            }
            catch (Exception ex)
            {
                string errMsg =
                    "Message: " + ex.Message +
                    Environment.NewLine +
                    Environment.NewLine +
                    "StackTrace: " + ex.StackTrace +
                    Environment.NewLine +
                    Environment.NewLine +
                    "Source: " + ex.Source +
                    Environment.NewLine +
                    Environment.NewLine +
                    "GetType: " + ex.GetType().ToString();

                System.Windows.Forms.Clipboard.SetDataObject(errMsg, true);

                // Create an EventLog instance and assign its source.
                EventLog myLog = new EventLog();
                myLog.Source = "ThreadException";
                myLog.WriteEntry(errMsg);

                MessageBox.Show(errMsg, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            finally
            {
                //if (stream != null)
                //{
                //    stream.Close();
                //    stream.Dispose();
                //}
            }
        }
Example #4
0
        //internal override void SaveData(BinaryWriter writer)
        internal override void SaveData(SnipStreamWrapper snipStreamWrapper)
        {
            bool hasRecordUnknown = false;
            //var position = writer.BaseStream.Position;
            var position = snipStreamWrapper.SnipStream.Position;
            //WriteString(writer, Name);
            snipStreamWrapper.WriteStringInFileStream(Name);

            var compressed = false;
            byte[] data;
            //using (var stream = new MemoryStream())
            //{

            //var dataWriter = new BinaryWriter(stream);
            snipStreamWrapper.ResetBufferSizeAndPosition();

            if (this.FormID == 496431)
                compressed = false;

            foreach (var subRecord in this.SubRecords)
            {
                //subRecord.SaveData(dataWriter);
                if (subRecord.Name == "????") hasRecordUnknown = true;
                subRecord.SaveData(snipStreamWrapper); //write data into buffer
            }

            uint realSize = snipStreamWrapper.OutputBufferLength;
            if (hasRecordUnknown) realSize = 0;

            //data = stream.ToArray();  //data = stream.ToArray();

            if (Properties.Settings.Default.UseDefaultRecordCompression)
            {
                compressed = ((this.Flags1 & 0x00040000) != 0) ||
                             (Properties.Settings.Default.EnableAutoCompress && Compressor.CompressRecord(Name))
                             ||
                             (Properties.Settings.Default.EnableCompressionLimit &&
                              (realSize >= Properties.Settings.Default.CompressionLimit));

                //if (compressed)
                //    data = ZLib.Compress(stream, CompressLevel.Best); //data = ZLib.Compress(data);
            }

            // ajouter dans zlib un option pour dire oui compresser ou dans le record une variable pour dire que c'est compressé
            if (Properties.Settings.Default.UsePluginRecordCompression)
            {
                compressed = (this.Flags1 & 0x00040000) != 0;
            }

            if (compressed & compressLevel != CompressLevel.None)
            {
                ZLib.Compress(snipStreamWrapper, compressLevel);
                data = new byte[ZLibWrapper.OutputBufferLength];
                ZLibWrapper.CopyOutputBufferIntoByteArray(data);
            }
            else
            {
                data = new byte[snipStreamWrapper.OutputBufferLength];
                if (snipStreamWrapper.OutputBufferLength > 0)
                    snipStreamWrapper.CopyOutputBufferToData(ref data);
                //data = stream.ToArray();  //data = stream.ToArray();
            }

            //} // using (var stream = new MemoryStream())

            var dataSize = (uint) data.Length;
            var flags = this.Flags1 & ~0x00040000U;
            if (compressed)
            {
                dataSize += 4;
                flags |= 0x00040000;

                Debug.WriteLineIf(
                    this.dataSize != dataSize,
                    string.Format("COMPRESSED RECORD [NAME={0} AT POSITION={1}] SIZE DIFFERS FROM ORIGINAL: ORIGINAL={2} ACTUAL={3}, RAW RECORD SIZE={4}",
                        Name, position, this.dataSize, dataSize, realSize));
            }

            snipStreamWrapper.WriteUInt32(dataSize);  //writer.Write(dataSize); // Size of compressed section + length
            snipStreamWrapper.WriteUInt32(flags);  //writer.Write(flags);
            snipStreamWrapper.WriteUInt32(FormID);  //writer.Write(this.FormID);
            snipStreamWrapper.WriteUInt32(Flags2);  //writer.Write(this.Flags2);
            snipStreamWrapper.WriteUInt32(Flags3);  //writer.Write(this.Flags3);
            if (compressed)
            {
                snipStreamWrapper.WriteUInt32(realSize);  //writer.Write(realSize);
            }
            if (dataSize > 0)
                snipStreamWrapper.WriteBytesArrayInFileStream(data); //writer.Write(data, 0, data.Length);
        }
Example #5
0
        private void LoadPluginData(FileStream fs, bool headerOnly, string[] recFilter) //LoadPluginData(BinaryReader br, bool headerOnly, string[] recFilter)
        {
            bool oldHoldUpdates = HoldUpdates;
            SnipStreamWrapper snipStreamWrapper = null;

            try
            {
                ZLibWrapper.AllocateBuffers();
                RecordsTace.InitListOfRecords();
                snipStreamWrapper = new SnipStreamWrapper(fs);
                //BinaryReader br = new BinaryReader(fs);

                string s;
                uint recsize;
                bool IsOblivion = false;

                this.Filtered = recFilter != null && recFilter.Length > 0;

                HoldUpdates = true;

                s = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                if (s != "TES4")
                {
                    throw new Exception("File is not a valid TES4 plugin (Missing TES4 record)");
                }

                // Check for file version by checking the position of the HEDR field in the file. (ie. how big are the record header.)
                snipStreamWrapper.JumpTo(20, SeekOrigin.Begin); //br.BaseStream.Position = 20;
                s = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                if (s == "HEDR")
                {
                    // Record Header is 20 bytes
                    IsOblivion = true;
                }
                else 
                {
                    s = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                    if (s != "HEDR")
                    {
                        throw new Exception("File is not a valid TES4 plugin (Missing HEDR subrecord in the TES4 record)");
                    }

                    // Record Header is 24 bytes. Or the file is illegal
                }

                snipStreamWrapper.JumpTo(4, SeekOrigin.Begin); //br.BaseStream.Position = 4;
                recsize = snipStreamWrapper.ReadUInt32(); //recsize = br.ReadUInt32();
                try
                {
                    this.AddRecord(new Record("TES4", recsize, snipStreamWrapper, IsOblivion));
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }

                if (!headerOnly)
                {
                    while (!snipStreamWrapper.Eof())  //while (br.PeekChar() != -1)
                    {
                        s = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                        recsize = snipStreamWrapper.ReadUInt32(); //recsize = br.ReadUInt32();
                        if (s == "GRUP")
                        {
                            try
                            {
                                this.AddRecord(new GroupRecord(recsize, snipStreamWrapper, IsOblivion, recFilter, false)); //this.AddRecord(new GroupRecord(recsize, br, IsOblivion, recFilter, false));
                            }
                            catch (Exception e)
                            {
                                MessageBox.Show(e.Message);
                            }
                        }
                        else
                        {
                            bool skip = recFilter != null && Array.IndexOf(recFilter, s) >= 0;
                            if (skip)
                            {
                                long size = recsize + (IsOblivion ? 8 : 12);
                                if ((snipStreamWrapper.ReadUInt32() & 0x00040000) > 0) //if ((br.ReadUInt32() & 0x00040000) > 0)
                                {
                                    size += 4; // Add 4 bytes for compressed record since the decompressed size is not included in the record size.
                                }

                                snipStreamWrapper.JumpTo((int)size, SeekOrigin.Current);  //br.BaseStream.Position += size; // just position past the data
                            }
                            else
                            {
                                try
                                {
                                    this.AddRecord(new Record(s, recsize, snipStreamWrapper, IsOblivion)); //this.AddRecord(new Record(s, recsize, br, IsOblivion));
                                }
                                catch (Exception e)
                                {
                                    MessageBox.Show(e.Message);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                snipStreamWrapper.CloseAndDisposeFileStream();
                snipStreamWrapper = null;
                Clipboard.SetText("CompressedRecords:" + Environment.NewLine +
                                  string.Join<string>(string.Empty, RecordsTace.CompressedRecords) +
                                  "AllRecords:" + Environment.NewLine +
                                  string.Join<string>(string.Empty, RecordsTace.AllRecords) +
                                  "Max Size:" +
                                  ZLibWrapper.MaxOutputBufferPosition.ToString(CultureInfo.InvariantCulture));
                ZLibWrapper.ReleaseBuffers();
                ZLib.ReleaseInflater();
                HoldUpdates = oldHoldUpdates;
                FireRecordListUpdate(this, this);
            }
        }
Example #6
0
        //internal override void SaveData(BinaryWriter writer)
        //{
        //    foreach (Rec r in this.Records)
        //    {
        //        r.SaveData(writer);
        //    }
        //}

        internal override void SaveData(SnipStreamWrapper snipStreamWrapper)
        {

            foreach (Rec r in this.Records)
            {
                r.SaveData(snipStreamWrapper);
            }
        }
Example #7
0
        internal void Save(string filePath)
        {
            UpdateRecordCount();
            string extension = string.Empty;
            //BinaryWriter bw;
            SnipStreamWrapper snipStreamWrapper = null;

            string tmpFile = filePath + ".new";

            //if (File.Exists(filePath))
            //{
            //    //bw = new BinaryWriter(File.OpenWrite(filePath + ".new"));
            //    //extension = ".new";
            //}
            //else
            //{
            //    //bw = new BinaryWriter(File.OpenWrite(filePath));
            //    fs = new FileStream(filePath, FileMode.Open, FileAccess.Write);
            //}

            //fs = new FileStream(filePath + extension, FileMode.Open, FileAccess.Write);
            //bw = new BinaryWriter(File.OpenWrite(filePath + extension));

            //bw = new BinaryWriter(File.OpenWrite(tmpFile));
            FileStream fs = new FileStream(tmpFile, FileMode.Create, FileAccess.Write, FileShare.None);

            try
            {
                ZLibWrapper.AllocateBuffers();
                snipStreamWrapper = new SnipStreamWrapper(fs);
                snipStreamWrapper.AllocateBuffers();

                this.SaveData(snipStreamWrapper);
                Name = Path.GetFileName(filePath);
                PluginPath = Path.GetDirectoryName(filePath);
            }
            finally
            {
                //bw.Close();                
                snipStreamWrapper.CloseAndDisposeFileStream();
                snipStreamWrapper.ReleaseBuffers();
                snipStreamWrapper = null;
                fs = null;
            }

            try
            {
                // ** Create Backup
                bool backupExists = true;
                int backupVersion = 0;
                string backupFolder = CreateBackupFolder(filePath);
                while (backupExists && backupVersion < 999)
                {
                    backupExists =
                        File.Exists(Path.Combine(backupFolder, Name) + string.Format(".{0,3:D3}.bak", backupVersion));
                    if (backupExists)
                    {
                        backupVersion++;
                    }
                }
                string backupFile = Path.Combine(backupFolder, Name) + string.Format(".{0,3:D3}.bak", backupVersion);
                File.Copy(tmpFile, backupFile, true);

                //if (existed)
                //{
                    ////string newFile = filePath;
                    //string backupFile = Path.Combine(backupFolder, Name) + string.Format(".{0,3:D3}.bak", backupVersion);
                    //File.Copy(tmpFile, backupFile, true);
                    if (File.Exists(filePath))
                    {
                        File.Delete(filePath);
                    }
                    File.Move(tmpFile, filePath);
                //}
        
            }
            catch (Exception ex)
            {
                string msg = string.Format(ex.Message);
                MessageBox.Show(
                    msg,
                    TranslateUI.TranslateUiGlobalization.ResManager.GetString("Application_Title"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                Clipboard.SetText(msg);
            }

            var tes4 = this.Records.OfType<Record>().FirstOrDefault(x => x.Name == "TES4");
            if (tes4 != null && (tes4.Flags1 & 0x80) != 0)
            {
                if (Properties.Settings.Default.SaveStringsFiles)
                {
                    string prefix = Path.Combine(Path.Combine(Path.GetDirectoryName(filePath), "Strings"), Path.GetFileNameWithoutExtension(filePath));
                    prefix += "_" + Properties.Settings.Default.LocalizationName;
                    this.SaveStrings(prefix);
                }
            }

            StringsDirty = false;
        }
Example #8
0
        //internal override void SaveData(BinaryWriter writer)
        //{
        //    throw new NotImplementedException();
        //}

        internal override void SaveData(SnipStreamWrapper snipStreamWrapper)
        {
            throw new NotImplementedException();
        }
Example #9
0
        /// <summary>
        /// Compress a stream with ZLib
        /// </summary>
        /// <param name="snipStreamWrapper">A stream wrapper object</param>
        /// <param name="compressLevel">Compression level of stream.</param>
        public static void Compress(SnipStreamWrapper snipStreamWrapper, CompressLevel compressLevel)
        {
            var numBytesAddressing = snipStreamWrapper.OutputBufferLength;

            ZLibWrapper.CopyByteArrayToInputBuffer(snipStreamWrapper.OutputBuffer, 0,
                                                   snipStreamWrapper.OutputBufferLength);

            if (_deflaterBest == null)
            {
                _deflaterBest = new Deflater(CompressLevel.Best);
                _deflaterBest.DataAvailable += ZLibWrapper.WriteInOutputBuffer;
            }

            if (_deflaterNone == null)
            {
                _deflaterNone = new Deflater(CompressLevel.None);
                _deflaterNone.DataAvailable += ZLibWrapper.WriteInOutputBuffer;
            }

            if (_deflaterFastest == null)
            {
                _deflaterFastest = new Deflater(CompressLevel.Fastest);
                _deflaterFastest.DataAvailable += ZLibWrapper.WriteInOutputBuffer;
            }

            if (_deflaterDefault == null)
            {
                _deflaterDefault = new Deflater(CompressLevel.Default);
                _deflaterDefault.DataAvailable += ZLibWrapper.WriteInOutputBuffer;
            }

            try
            {
                while (numBytesAddressing > 0u)
                {
                    uint numBytes = Math.Min(numBytesAddressing, 8192u); //8192u); 65536u

                    if (compressLevel == CompressLevel.None)
                    {
                        _deflaterNone.Add(ZLibWrapper.ReadBytes((int)numBytes, ZLibBufferType.InputBuffer));
                    }

                    if (compressLevel == CompressLevel.Best)
                    {
                        _deflaterBest.Add(ZLibWrapper.ReadBytes((int)numBytes, ZLibBufferType.InputBuffer));
                    }

                    if (compressLevel == CompressLevel.Default)
                    {
                        _deflaterDefault.Add(ZLibWrapper.ReadBytes((int)numBytes, ZLibBufferType.InputBuffer));
                    }

                    if (compressLevel == CompressLevel.Fastest)
                    {
                        _deflaterFastest.Add(ZLibWrapper.ReadBytes((int)numBytes, ZLibBufferType.InputBuffer));
                    }

                    numBytesAddressing -= numBytes;
                }

                string deflateErrorMsg = string.Empty;
                if (compressLevel == CompressLevel.None)
                {
                    deflateErrorMsg = _deflaterNone._ztream.msg;
                }

                if (compressLevel == CompressLevel.Best)
                {
                    deflateErrorMsg = _deflaterBest._ztream.msg;
                }

                if (compressLevel == CompressLevel.Default)
                {
                    deflateErrorMsg = _deflaterDefault._ztream.msg;
                }

                if (compressLevel == CompressLevel.Fastest)
                {
                    deflateErrorMsg = _deflaterFastest._ztream.msg;
                }

                if (!string.IsNullOrWhiteSpace(deflateErrorMsg))
                {
                    MessageBox.Show(string.Format("ZLib.Compress: {0}", deflateErrorMsg),
                                    TranslateUI.TranslateUiGlobalization.ResManager.GetString("ZLib_Error"),
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                }

                if (compressLevel == CompressLevel.None)
                {
                    _deflaterNone.Finish(); // flush zlib buffer
                }
                if (compressLevel == CompressLevel.Best)
                {
                    _deflaterBest.Finish(); // flush zlib buffer
                }
                if (compressLevel == CompressLevel.Default)
                {
                    _deflaterDefault.Finish(); // flush zlib buffer
                }
                if (compressLevel == CompressLevel.Fastest)
                {
                    _deflaterFastest.Finish(); // flush zlib buffer
                }
                ZLibWrapper.Position(0, ZLibBufferType.OutputBuffer);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    string.Format(TranslateUI.TranslateUiGlobalization.ResManager.GetString(name: "MSG_ErrorWithNewLine"), arg0: ex),
                    TranslateUI.TranslateUiGlobalization.ResManager.GetString(name: "ZLib_Compress"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
            finally
            {
                if (ZLibWrapper.OutputBufferLength == 0)
                {
                    MessageBox.Show(
                        TranslateUI.TranslateUiGlobalization.ResManager.GetString(name: "ZLib_OutputBufferEmpty"),
                        TranslateUI.TranslateUiGlobalization.ResManager.GetString(name: "ZLib_Compress"),
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
            }
        }