Пример #1
0
        /// <summary>
        /// 处理写。
        /// </summary>
        /// <param name="state">状态。</param>
        private void PerpetualWriterMethod(object state)
        {
#if Zip_Trace
            TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod START");
#endif
            try {
                do
                {
                    // wait for the next session
#if Zip_Trace
                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    _sessionReset.WaitOne(begin) PWM");
#endif
                    _sessionReset.WaitOne();
#if Zip_Trace
                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    _sessionReset.WaitOne(done)  PWM");
#endif
                    if (_isDisposed)
                    {
                        break;
                    }
#if Zip_Trace
                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    _sessionReset.Reset()        PWM");
#endif
                    _sessionReset.Reset();

                    // repeatedly write buffers as they become ready
                    WorkItem           workitem = null;
                    Py.Algorithm.Crc32 c        = new Py.Algorithm.Crc32();
                    do
                    {
                        workitem = _pool[_nextToWrite % _pc];
                        lock (workitem) {
#if Zip_Trace
                            if (_noMoreInputForThisSegment)
                            {
                                TraceOutput(TraceBits.Write,
                                            "Write    drain    wi({0}) stat({1}) canuse({2})  cba({3})",
                                            workitem.Index,
                                            workitem.CurrentStatus,
                                            (workitem.CurrentStatus == WorkItem.Status.Compressed),
                                            workitem.CompressedBytesAvailable);
                            }
#endif

                            do
                            {
                                if (workitem.CurrentStatus == WorkItem.Status.Compressed)
                                {
#if Zip_Trace
                                    TraceOutput(TraceBits.WriteBegin,
                                                "Write    begin    wi({0}) stat({1})              cba({2})",
                                                workitem.Index,
                                                workitem.CurrentStatus,
                                                workitem.CompressedBytesAvailable);
#endif

                                    workitem.CurrentStatus = WorkItem.Status.Writing;
                                    _outStream.Write(workitem.Compressed, 0, workitem.CompressedBytesAvailable);
                                    c.Combine(workitem.Crc, workitem.InputBytesAvailable);
                                    _totalBytesProcessed += workitem.InputBytesAvailable;
                                    _nextToWrite++;
                                    workitem.InputBytesAvailable = 0;
                                    workitem.CurrentStatus       = WorkItem.Status.Done;
#if Zip_Trace
                                    TraceOutput(TraceBits.WriteDone,
                                                "Write    done     wi({0}) stat({1})              cba({2})",
                                                workitem.Index,
                                                workitem.CurrentStatus,
                                                workitem.CompressedBytesAvailable);
#endif
                                    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.CurrentStatus != WorkItem.Status.Compressed)
                                    {
#if Zip_Trace
                                        TraceOutput(TraceBits.WriteWait,
                                                    "Write    waiting  wi({0}) stat({1}) nw({2}) nf({3}) nomore({4})",
                                                    workitem.Index,
                                                    workitem.CurrentStatus,
                                                    _nextToWrite, _nextToFill,
                                                    _noMoreInputForThisSegment);
#endif
                                        if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill)
                                        {
                                            break;
                                        }

                                        wcycles++;

                                        // wake up someone else
                                        Monitor.Pulse(workitem);
                                        // release and wait
                                        Monitor.Wait(workitem);
#if Zip_Trace
                                        if (workitem.CurrentStatus == WorkItem.Status.Compressed)
                                        {
                                            TraceOutput(TraceBits.WriteWait,
                                                        "Write    A-OK     wi({0}) stat({1}) iba({2}) cba({3}) cyc({4})",
                                                        workitem.Index,
                                                        workitem.CurrentStatus,
                                                        workitem.InputBytesAvailable,
                                                        workitem.CompressedBytesAvailable,
                                                        wcycles);
                                        }
#endif
                                    }

                                    if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill)
                                    {
                                        break;
                                    }
                                }
                            }while (true);
                        }
#if Zip_Trace
                        if (_noMoreInputForThisSegment)
                        {
                            TraceOutput(TraceBits.Write,
                                        "Write    nomore  nw({0}) nf({1}) break({2})",
                                        _nextToWrite, _nextToFill, (_nextToWrite == _nextToFill));
                        }
#endif
                        if (_noMoreInputForThisSegment && _nextToWrite == _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();
                    ZlibState 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 != ZlibState.StreamEnd && rc != ZlibState.Success)
                    {
                        throw new ZlibException("压缩错误: " + compressor.Message);
                    }

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

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

#if Zip_Trace
                        TraceOutput(TraceBits.WriteBegin,
                                    "Write    done     flush");
#endif
                    }

                    compressor.EndDeflate();

                    _Crc32 = c.Crc32Result;

                    // signal that writing is complete:
#if Zip_Trace
                    TraceOutput(TraceBits.Synch, "Synch    _writingDone.Set()           PWM");
#endif
                    _writingDone.Set();
                }while (true);
            } catch (System.Exception exc1) {
                lock (_eLock) {
                    // expose the exception to the main thread
                    if (_pendingException != null)
                    {
                        _pendingException = exc1;
                    }
                }
            }
#if Zip_Trace
            TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod FINIS");
#endif
        }
Пример #2
0
        /// <summary>
        /// 压缩一个内容。
        /// </summary>
        /// <param name="wi">内容。</param>
        private void DeflateOne(Object wi)
        {
            WorkItem workitem = (WorkItem)wi;

            try {
                // compress one buffer
                int myItem = workitem.Index;

                lock (workitem) {
                    if (workitem.CurrentStatus != WorkItem.Status.Filled)
                    {
                        throw new InvalidOperationException();
                    }

                    Py.Algorithm.Crc32 crc = new Py.Algorithm.Crc32();

                    // use the workitem:
                    // calc CRC on the buffer
                    crc.SlurpBlock(workitem.Buffer, 0, workitem.InputBytesAvailable);

                    #region 压缩

                    ZlibCodec compressor = workitem.Compressor;
                    ZlibState rc;
                    compressor.ResetDeflate();
                    compressor.NextIn = 0;

                    compressor.AvailableBytesIn = workitem.InputBytesAvailable;

                    // 第 1 步: 压缩缓存
                    compressor.NextOut           = 0;
                    compressor.AvailableBytesOut = workitem.Compressed.Length;
                    do
                    {
                        compressor.Deflate(FlushType.None);
                    } while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0);

                    // 第 2 步: 异步输出缓存
                    rc = compressor.Deflate(FlushType.Sync);

                    workitem.CompressedBytesAvailable = (int)compressor.TotalBytesOut;

                    #endregion


                    // 更新状态
                    workitem.CurrentStatus = WorkItem.Status.Compressed;
                    workitem.Crc           = crc.Crc32Result;
#if Zip_Trace
                    TraceOutput(TraceBits.Compress,
                                "Compress          wi({0}) stat({1}) len({2})",
                                workitem.Index,
                                workitem.CurrentStatus,
                                workitem.CompressedBytesAvailable
                                );
#endif

                    // release the item
                    Monitor.Pulse(workitem);
                }
            } catch (System.Exception exc1) {
                lock (_eLock) {
                    // expose the exception to the main thread
                    if (_pendingException != null)
                    {
                        _pendingException = exc1;
                    }
                }
            }
        }