public WorkItem(int size,
                        CompressionLevel compressLevel,
                        CompressionStrategy strategy,
                        int ix)
        {
            this.buffer = new byte[size];
            // alloc 5 bytes overhead for every block (margin of safety= 2)
            int n = size + (size / 32768 + 1) * 5 * 2;

            this.compressed = new byte[n];
            this.compressor = new ZLibCodec();
            this.compressor.InitializeDeflate(compressLevel, false);
            this.compressor.OutputBuffer = this.compressed;
            this.compressor.InputBuffer  = this.buffer;
            this.index = ix;
        }
Example #2
0
        private void end()
        {
            if (this.z == null)
            {
                return;
            }

            if (this.m_wantCompress)
            {
                this.m_z.EndDeflate();
            }
            else
            {
                this.m_z.EndInflate();
            }

            this.m_z = null;
        }
        internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZLibCodec z)
        {
            int result;

            this.initWorkArea(19);
            this.hn[0] = 0;
            result     = this.huft_build(c, 0, 19, 19, null, null, tb, bb, hp, this.hn, this.v);

            if (result == InfTree.Z_DATA_ERROR)
            {
                z.Message = "oversubscribed dynamic bit lengths tree";
            }
            else if (result == InfTree.Z_BUF_ERROR || bb[0] == 0)
            {
                z.Message = "incomplete dynamic bit lengths tree";
                result    = InfTree.Z_DATA_ERROR;
            }

            return(result);
        }
        private void m_FlushFinish()
        {
            // After writing a series of compressed buffers, each one closed
            // with Flush.Sync, we now write the final one as Flush.Finish,
            // and then stop.
            byte[]    buffer     = new byte[128];
            ZLibCodec compressor = new ZLibCodec();
            int       rc         = compressor.InitializeDeflate(this.m_compressLevel, false);

            compressor.InputBuffer       = null;
            compressor.NextIn            = 0;
            compressor.AvailableBytesIn  = 0;
            compressor.OutputBuffer      = buffer;
            compressor.NextOut           = 0;
            compressor.AvailableBytesOut = buffer.Length;
            rc = compressor.Deflate(FlushType.Finish);

            if (rc != ZLibConstants.Z_STREAM_END && rc != ZLibConstants.Z_OK)
            {
                throw new Exception("deflating: " + compressor.Message);
            }

            if (buffer.Length - compressor.AvailableBytesOut > 0)
            {
                this.TraceOutput(TraceBits.EmitBegin,
                                 "Emit     begin    flush bytes({0})",
                                 buffer.Length - compressor.AvailableBytesOut);

                this.m_outStream.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);

                this.TraceOutput(TraceBits.EmitDone,
                                 "Emit     done     flush");
            }

            compressor.EndDeflate();

            this.Crc32 = this.m_runningCrc.Crc32Result;
        }
        private bool DeflateOneSegment(WorkItem workitem)
        {
            ZLibCodec compressor = workitem.compressor;
            int       rc         = 0;

            compressor.ResetDeflate();
            compressor.NextIn = 0;

            compressor.AvailableBytesIn = workitem.inputBytesAvailable;

            // step 1: deflate the buffer
            compressor.NextOut           = 0;
            compressor.AvailableBytesOut = workitem.compressed.Length;
            do
            {
                compressor.Deflate(FlushType.None);
            } while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0);

            // step 2: flush (sync)
            rc = compressor.Deflate(FlushType.Sync);

            workitem.compressedBytesAvailable = (int)compressor.TotalBytesOut;
            return(true);
        }
 internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZLibCodec z)
 {
     bl[0] = InfTree.fixed_bl;
     bd[0] = InfTree.fixed_bd;
     tl[0] = InfTree.fixed_tl;
     td[0] = InfTree.fixed_td;
     return(InfTree.Z_OK);
 }
        internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZLibCodec z)
        {
            int result;

            // build literal/length tree
            this.initWorkArea(288);
            this.hn[0] = 0;
            result     = this.huft_build(c, 0, nl, 257, InfTree.cplens, InfTree.cplext, tl, bl, hp, this.hn, this.v);
            if (result != InfTree.Z_OK || bl[0] == 0)
            {
                if (result == InfTree.Z_DATA_ERROR)
                {
                    z.Message = "oversubscribed literal/length tree";
                }
                else if (result != InfTree.Z_MEM_ERROR)
                {
                    z.Message = "incomplete literal/length tree";
                    result    = InfTree.Z_DATA_ERROR;
                }

                return(result);
            }

            // build distance tree
            this.initWorkArea(288);
            result = this.huft_build(c, nl, nd, 0, InfTree.cpdist, InfTree.cpdext, td, bd, hp, this.hn, this.v);

            if (result != InfTree.Z_OK || bd[0] == 0 && nl > 257)
            {
                if (result == InfTree.Z_DATA_ERROR)
                {
                    z.Message = "oversubscribed distance tree";
                }
                else if (result == InfTree.Z_BUF_ERROR)
                {
                    z.Message = "incomplete distance tree";
                    result    = InfTree.Z_DATA_ERROR;
                }
                else if (result != InfTree.Z_MEM_ERROR)
                {
                    z.Message = "empty distance tree with lengths";
                    result    = InfTree.Z_DATA_ERROR;
                }

                return(result);
            }

            return(InfTree.Z_OK);
        }
        private void m_PerpetualWriterMethod(object state)
        {
            TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod START");

            try
            {
                do
                {
                    // wait for the next session
                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    m_sessionReset.WaitOne(begin) PWM");
                    m_sessionReset.WaitOne();
                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    m_sessionReset.WaitOne(done)  PWM");

                    if (_isDisposed)
                    {
                        break;
                    }

                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    m_sessionReset.Reset()        PWM");
                    m_sessionReset.Reset();

                    // repeatedly write buffers as they become ready
                    WorkItem workitem = null;
                    Supercell.Magic.Servers.Core.Libs.ZLib.CRC32 c = new Supercell.Magic.Servers.Core.Libs.ZLib.CRC32();
                    do
                    {
                        workitem = m_pool[_nextToWrite % m_pc];
                        lock (workitem)
                        {
                            if (_noMoreInputForThisSegment)
                            {
                                TraceOutput(TraceBits.Write,
                                            "Write    drain    wi({0}) stat({1}) canuse({2})  cba({3})",
                                            workitem.index,
                                            workitem.status,
                                            (workitem.status == (int)WorkItem.Status.Compressed),
                                            workitem.compressedBytesAvailable);
                            }

                            do
                            {
                                if (workitem.status == (int)WorkItem.Status.Compressed)
                                {
                                    TraceOutput(TraceBits.WriteBegin,
                                                "Write    begin    wi({0}) stat({1})              cba({2})",
                                                workitem.index,
                                                workitem.status,
                                                workitem.compressedBytesAvailable);

                                    workitem.status = (int)WorkItem.Status.Writing;
                                    m_outStream.Write(workitem.compressed, 0, workitem.compressedBytesAvailable);
                                    c.Combine(workitem.crc, workitem.inputBytesAvailable);
                                    m_totalBytesProcessed += workitem.inputBytesAvailable;
                                    m_nextToWrite++;
                                    workitem.inputBytesAvailable = 0;
                                    workitem.status = (int)WorkItem.Status.Done;

                                    TraceOutput(TraceBits.WriteDone,
                                                "Write    done     wi({0}) stat({1})              cba({2})",
                                                workitem.index,
                                                workitem.status,
                                                workitem.compressedBytesAvailable);


                                    Monitor.Pulse(workitem);
                                    break;
                                }
                                else
                                {
                                    int wcycles = 0;
                                    // I've locked a workitem I cannot use.
                                    // Therefore, wake someone else up, and then release the lock.
                                    while (workitem.status != (int)WorkItem.Status.Compressed)
                                    {
                                        TraceOutput(TraceBits.WriteWait,
                                                    "Write    waiting  wi({0}) stat({1}) nw({2}) nf({3}) nomore({4})",
                                                    workitem.index,
                                                    workitem.status,
                                                    m_nextToWrite, m_nextToFill,
                                                    m_noMoreInputForThisSegment);

                                        if (_noMoreInputForThisSegment && m_nextToWrite == m_nextToFill)
                                        {
                                            break;
                                        }

                                        wcycles++;

                                        // wake up someone else
                                        Monitor.Pulse(workitem);
                                        // release and wait
                                        Monitor.Wait(workitem);

                                        if (workitem.status == (int)WorkItem.Status.Compressed)
                                        {
                                            TraceOutput(TraceBits.WriteWait,
                                                        "Write    A-OK     wi({0}) stat({1}) iba({2}) cba({3}) cyc({4})",
                                                        workitem.index,
                                                        workitem.status,
                                                        workitem.inputBytesAvailable,
                                                        workitem.compressedBytesAvailable,
                                                        wcycles);
                                        }
                                    }

                                    if (_noMoreInputForThisSegment && m_nextToWrite == m_nextToFill)
                                    {
                                        break;
                                    }
                                }
                            }while (true);
                        }

                        if (_noMoreInputForThisSegment)
                        {
                            TraceOutput(TraceBits.Write,
                                        "Write    nomore  nw({0}) nf({1}) break({2})",
                                        m_nextToWrite, m_nextToFill, (_nextToWrite == m_nextToFill));
                        }

                        if (_noMoreInputForThisSegment && m_nextToWrite == m_nextToFill)
                        {
                            break;
                        }
                    } while (true);


                    // Finish:
                    // After writing a series of buffers, closing each one with
                    // Flush.Sync, we now write the final one as Flush.Finish, and
                    // then stop.
                    byte[]    buffer     = new byte[128];
                    ZLibCodec compressor = new ZLibCodec();
                    int       rc         = compressor.InitializeDeflate(_compressLevel, false);
                    compressor.InputBuffer       = null;
                    compressor.NextIn            = 0;
                    compressor.AvailableBytesIn  = 0;
                    compressor.OutputBuffer      = buffer;
                    compressor.NextOut           = 0;
                    compressor.AvailableBytesOut = buffer.Length;
                    rc = compressor.Deflate(FlushType.Finish);

                    if (rc != ZLibConstants.Z_STREAM_END && rc != ZLibConstants.Z_OK)
                    {
                        throw new Exception("deflating: " + compressor.Message);
                    }

                    if (buffer.Length - compressor.AvailableBytesOut > 0)
                    {
                        TraceOutput(TraceBits.WriteBegin,
                                    "Write    begin    flush bytes({0})",
                                    buffer.Length - compressor.AvailableBytesOut);

                        m_outStream.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);

                        TraceOutput(TraceBits.WriteBegin,
                                    "Write    done     flush");
                    }

                    compressor.EndDeflate();

                    m_Crc32 = c.Crc32Result;

                    // signal that writing is complete:
                    TraceOutput(TraceBits.Synch, "Synch    m_writingDone.Set()           PWM");
                    m_writingDone.Set();
                }while (true);
            }
            catch (System.Exception exc1)
            {
                lock (_eLock)
                {
                    // expose the exception to the main thread
                    if (_pendingException != null)
                    {
                        m_pendingException = exc1;
                    }
                }
            }

            TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod FINIS");
        }