Beispiel #1
0
        /// <summary>
        /// Refills the inflater with compressed data if it needs input. (And only if
        /// it needs input). Returns true if the inflater required input but the source
        /// was exhausted.
        /// </summary>
        /// <returns></returns>
        public bool Refill()
        {
            if (!inflater.IsNeedingInput)
            {
                return(false);
            }

            ReleaseInflatedBytes();

            if (inflater.RemainingInput != 0)
            {
                throw new IllegalStateException("?");                               // TODO: possible?
            }
            // If there are compressed bytes in the source, assign them to the inflater.
            if (source.Exhausted())
            {
                return(true);
            }

            // Assign buffer bytes to the inflater.
            Segment head = source.Buffer().Head;

            bufferBytesHeldByInflater = head.Limit - head.Pos;
            inflater.SetInput(head.Data, head.Pos, bufferBytesHeldByInflater);
            return(false);
        }
Beispiel #2
0
        public long Read(EasyBuffer sink, long byteCount)
        {
            if (byteCount < 0)
            {
                throw new ArgumentException("byteCount < 0: " + byteCount);
            }
            if (byteCount == 0)
            {
                return(0);
            }

            // If we haven't consumed the header, we must consume it before anything else.
            if (section == SECTION_HEADER)
            {
                ConsumeHeader();
                section = SECTION_BODY;
            }

            // Attempt to read at least a byte of the body. If we do, we're done.
            if (section == SECTION_BODY)
            {
                long offset = sink.Size;
                long result = inflaterSource.Read(sink, byteCount);
                if (result > 0)//!=-1
                {
                    UpdateCrc(sink, offset, result);
                    return(result);
                }
                section = SECTION_TRAILER;
            }

            // The body is exhausted; time to read the trailer. We always consume the
            // trailer before returning a -1 exhausted result; that way if you read to
            // the end of a GzipSource you guarantee that the CRC has been checked.
            if (section == SECTION_TRAILER)
            {
                ConsumeTrailer();
                section = SECTION_DONE;

                // Gzip streams self-terminate: they return -1 before their underlying
                // source returns -1. Here we attempt to force the underlying stream to
                // return -1 which may trigger it to release its resources. If it doesn't
                // return -1, then our Gzip data finished prematurely!
                if (!source.Exhausted())
                {
                    throw new Exception("gzip finished without exhausting source");
                }
            }

            return(-1);
        }