Exemple #1
0
 public ZlibBaseStream(System.IO.Stream stream,
                       CompressionMode compressionMode,
                       CompressionLevel level,
                       ZlibStreamFlavor flavor,
                       bool leaveOpen)
     : base()
 {
     this._flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     this._stream = stream;
     this._leaveOpen = leaveOpen;
     this._compressionMode = compressionMode;
     this._flavor = flavor;
     this._level = level;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP)
     {
         crc = new CRC32();
     }
 }
Exemple #2
0
        private bool _ExtractTo( int index, Stream output, int outBufRemain )
        {
            XUnzipFileInfo fileInfo = _GetFileInfo ( index );

            BinaryReader br = new BinaryReader ( inputStream );

            if ( fileInfo.offsetData == -1 )
            {
                if ( inputStream.Seek ( fileInfo.offsetLocalHeader, SeekOrigin.Begin ) != fileInfo.offsetLocalHeader )
                    throw new Exception ( XUNZIP_ERR.CANT_READ_FILE.ToString () );
                if ( !ReadLocalHeader ( ref fileInfo, br ) )
                    return false;
            }

            inputStream.Seek ( fileInfo.offsetData, SeekOrigin.Begin );

            byte [] bufIn;
            int inputRemain;
            int outputRemain;
            int toRead;
            uint crc32 = 0;

            bufIn = new byte [ 32768 ];

            inputRemain = fileInfo.compressedSize;
            outputRemain = fileInfo.uncompressedSize;

            if ( fileInfo.method == XUNZIP_COMPRESSION_METHOD.METHOD_STORE )
            {
                CRC32 crcGen = new CRC32 ();
                while ( inputRemain > 0 )
                {
                    toRead = System.Math.Min ( System.Math.Min ( 32768, inputRemain ), outputRemain );

                    int temp = br.Read ( bufIn, 0, toRead );
                    output.Write ( bufIn, 0, toRead );
                    crcGen.Update ( bufIn, 0, toRead );
                    crc32 = crcGen.Result;

                    inputRemain -= toRead;
                    outputRemain -= temp;
                }
            }
            else
            {
                DeflateStream stream = new DeflateStream ( inputStream, CompressionMode.Decompress );

                CRC32 crcGen = new CRC32 ();
                while ( inputRemain > 0 )
                {
                    toRead = System.Math.Min ( System.Math.Min ( 32768, inputRemain ), outputRemain );

                    int temp = stream.Read ( bufIn, 0, outputRemain );
                    output.Write ( bufIn, 0, temp );
                    crcGen.Update ( bufIn, 0, toRead );
                    crc32 = crcGen.Result;

                    inputRemain -= toRead;
                    outputRemain -= temp;
                }
            }

            //if ( crc32 != fileInfo.crc32 )
            //return false;

            if ( outputRemain > 0 )
                return false;

            output.Position = 0;

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

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

                    if (_isDisposed) break;

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

                    // repeatedly write buffers as they become ready
                    WorkItem workitem = null;
                    var c = new CRC32();
                    do
                    {
                        workitem = _pool[_nextToWrite % _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;
                                    _outStream.Write(workitem.compressed, 0, workitem.compressedBytesAvailable);
                                    c.Combine(workitem.crc, workitem.inputBytesAvailable);
                                    _totalBytesProcessed += workitem.inputBytesAvailable;
                                    _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,
                                                    _nextToWrite, _nextToFill,
                                                    _noMoreInputForThisSegment);

                                        if (_noMoreInputForThisSegment && _nextToWrite == _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 && _nextToWrite == _nextToFill)
                                        break;
                                }
                            } while (true);
                        }

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

                        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.
                    var buffer = new byte[128];
                    var 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);

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

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

                    compressor.EndDeflate();

                    _Crc32 = c.Crc32Result;

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

            TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod FINIS");
        }
        private void _DeflateOne(Object wi)
        {
            var workitem = (WorkItem)wi;
            try
            {
                // compress one buffer
                //int myItem = workitem.index;

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

                    var crc = new CRC32();

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

                    // deflate it
                    DeflateOneSegment(workitem);

                    // update status
                    workitem.status = (int)WorkItem.Status.Compressed;
                    workitem.crc = crc.Crc32Result;

                    TraceOutput(TraceBits.Compress,
                                "Compress          wi({0}) stat({1}) len({2})",
                                workitem.index,
                                workitem.status,
                                workitem.compressedBytesAvailable
                        );

                    // release the item
                    Monitor.Pulse(workitem);
                }
            }
            catch (Exception exc1)
            {
                lock (_eLock)
                {
                    // expose the exception to the main thread
                    if (_pendingException != null)
                        _pendingException = exc1;
                }
            }
        }
Exemple #5
0
        private void _PerpetualWriterMethod(object state)
        {
            try
            {
                WorkItem item;
                CRC32    crc;
TR_0020:
                while (true)
                {
                    this._sessionReset.WaitOne();
                    if (this._isDisposed)
                    {
                        break;
                    }
                    this._sessionReset.Reset();
                    item = null;
                    crc  = new CRC32();
                    goto TR_001C;
                }
                return;

TR_000E:
                if (this._noMoreInputForThisSegment)
                {
                }
                if (!this._noMoreInputForThisSegment || (this._nextToWrite != this._nextToFill))
                {
                    goto TR_001C;
                }
                else
                {
                    byte[]    buffer = new byte[0x80];
                    ZlibCodec codec  = new ZlibCodec();
                    int       num2   = codec.InitializeDeflate(this._compressLevel, false);
                    codec.InputBuffer       = null;
                    codec.NextIn            = 0;
                    codec.AvailableBytesIn  = 0;
                    codec.OutputBuffer      = buffer;
                    codec.NextOut           = 0;
                    codec.AvailableBytesOut = buffer.Length;
                    num2 = codec.Deflate(FlushType.Finish);
                    if ((num2 != 1) && (num2 != 0))
                    {
                        throw new Exception("deflating: " + codec.Message);
                    }
                    if ((buffer.Length - codec.AvailableBytesOut) > 0)
                    {
                        this._outStream.Write(buffer, 0, buffer.Length - codec.AvailableBytesOut);
                    }
                    codec.EndDeflate();
                    this._Crc32 = crc.Crc32Result;
                    this._writingDone.Set();
                }
                goto TR_0020;
TR_001C:
                while (true)
                {
                    item = this._pool[this._nextToWrite % this._pc];
                    object obj2 = item;
                    lock (obj2)
                    {
                        if (this._noMoreInputForThisSegment)
                        {
                        }
                        while (true)
                        {
                            if (item.status != 4)
                            {
                                int num = 0;
                                while (true)
                                {
                                    if ((item.status != 4) && (!this._noMoreInputForThisSegment || (this._nextToWrite != this._nextToFill)))
                                    {
                                        num++;
                                        Monitor.Pulse(item);
                                        Monitor.Wait(item);
                                        if (item.status == 4)
                                        {
                                        }
                                        continue;
                                    }
                                    if (!this._noMoreInputForThisSegment || (this._nextToWrite != this._nextToFill))
                                    {
                                        break;
                                    }
                                    break;
                                }
                                continue;
                            }
                            else
                            {
                                item.status = 5;
                                this._outStream.Write(item.compressed, 0, item.compressedBytesAvailable);
                                crc.Combine(item.crc, item.inputBytesAvailable);
                                this._totalBytesProcessed += item.inputBytesAvailable;
                                this._nextToWrite++;
                                item.inputBytesAvailable = 0;
                                item.status = 6;
                                Monitor.Pulse(item);
                            }
                            break;
                        }
                    }
                    break;
                }
                goto TR_000E;
            }
            catch (Exception exception)
            {
                lock (this._eLock)
                {
                    if (this._pendingException != null)
                    {
                        this._pendingException = exception;
                    }
                }
            }
        }
 // This ctor is private - no validation is done here.  This is to allow the use
 // of a (specific) negative value for the _lengthLimit, to indicate that there
 // is no length set.  So we validate the length limit in those ctors that use an
 // explicit param, otherwise we don't validate, because it could be our special
 // value.
 private CrcCalculatorStream(bool leaveOpen, Int64 length, Stream stream)
 {
     _innerStream = stream;
     _Crc32 = new CRC32();
     _lengthLimit = length;
     _leaveOpen = leaveOpen;
 }