/// <exception cref="System.IO.IOException"/> public BZip2CompressionInputStream(InputStream @in, long start, long end, SplittableCompressionCodec.READ_MODE readMode) : base(@in, start, end) { // class data starts here// // Following state machine handles different states of compressed stream // position // HOLD : Don't advertise compressed stream position // ADVERTISE : Read 1 more character and advertise stream position // See more comments about it before updatePos method. // class data ends here// needsReset = false; bufferedIn = new BufferedInputStream(base.@in); this.startingPos = base.GetPos(); this.readMode = readMode; if (this.startingPos == 0) { // We only strip header if it is start of file bufferedIn = ReadStreamHeader(); } input = new CBZip2InputStream(bufferedIn, readMode); if (this.isHeaderStripped) { input.UpdateReportedByteCount(HeaderLen); } if (this.isSubHeaderStripped) { input.UpdateReportedByteCount(SubHeaderLen); } this.UpdatePos(false); }
/// <summary>Create a stream as dictated by the readMode.</summary> /// <remarks> /// Create a stream as dictated by the readMode. This method is used when /// the codecs wants the ability to work with the underlying stream positions. /// </remarks> /// <param name="seekableIn">The seekable input stream (seeks in compressed data)</param> /// <param name="start"> /// The start offset into the compressed stream. May be changed /// by the underlying codec. /// </param> /// <param name="end"> /// The end offset into the compressed stream. May be changed by /// the underlying codec. /// </param> /// <param name="readMode"> /// Controls whether stream position is reported continuously /// from the compressed stream only only at block boundaries. /// </param> /// <returns>a stream to read uncompressed bytes from</returns> /// <exception cref="System.IO.IOException"/> public abstract SplitCompressionInputStream CreateInputStream(InputStream seekableIn , Decompressor decompressor, long start, long end, SplittableCompressionCodec.READ_MODE readMode);
/// <summary> /// Creates CompressionInputStream to be used to read off uncompressed data /// in one of the two reading modes. /// </summary> /// <remarks> /// Creates CompressionInputStream to be used to read off uncompressed data /// in one of the two reading modes. i.e. Continuous or Blocked reading modes /// </remarks> /// <param name="seekableIn">The InputStream</param> /// <param name="start">The start offset into the compressed stream</param> /// <param name="end">The end offset into the compressed stream</param> /// <param name="readMode"> /// Controls whether progress is reported continuously or /// only at block boundaries. /// </param> /// <returns>CompressionInputStream for BZip2 aligned at block boundaries</returns> /// <exception cref="System.IO.IOException"/> public virtual SplitCompressionInputStream CreateInputStream(InputStream seekableIn , Decompressor decompressor, long start, long end, SplittableCompressionCodec.READ_MODE readMode) { if (!(seekableIn is Seekable)) { throw new IOException("seekableIn must be an instance of " + typeof(Seekable).FullName ); } //find the position of first BZip2 start up marker ((Seekable)seekableIn).Seek(0); // BZip2 start of block markers are of 6 bytes. But the very first block // also has "BZh9", making it 10 bytes. This is the common case. But at // time stream might start without a leading BZ. long FirstBzip2BlockMarkerPosition = CBZip2InputStream.NumberOfBytesTillNextMarker (seekableIn); long adjStart = Math.Max(0L, start - FirstBzip2BlockMarkerPosition); ((Seekable)seekableIn).Seek(adjStart); SplitCompressionInputStream @in = new BZip2Codec.BZip2CompressionInputStream(seekableIn , adjStart, end, readMode); // The following if clause handles the following case: // Assume the following scenario in BZip2 compressed stream where // . represent compressed data. // .....[48 bit Block].....[48 bit Block].....[48 bit Block]... // ........................[47 bits][1 bit].....[48 bit Block]... // ................................^[Assume a Byte alignment here] // ........................................^^[current position of stream] // .....................^^[We go back 10 Bytes in stream and find a Block marker] // ........................................^^[We align at wrong position!] // ...........................................................^^[While this pos is correct] if (@in.GetPos() < start) { ((Seekable)seekableIn).Seek(start); @in = new BZip2Codec.BZip2CompressionInputStream(seekableIn, start, end, readMode ); } return(@in); }