/// <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); }
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); }