ChecksumVerifyingInputStream.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *   https://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing,
  13.  * software distributed under the License is distributed on an
  14.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15.  * KIND, either express or implied.  See the License for the
  16.  * specific language governing permissions and limitations
  17.  * under the License.
  18.  */
  19. package org.apache.commons.compress.utils;

  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.util.zip.CheckedInputStream;
  23. import java.util.zip.Checksum;

  24. /**
  25.  * Verifies the checksum of the data read once the stream is exhausted.
  26.  *
  27.  * @NotThreadSafe
  28.  * @since 1.7
  29.  * @deprecated Use {@link org.apache.commons.io.input.ChecksumInputStream}.
  30.  */
  31. @Deprecated
  32. public class ChecksumVerifyingInputStream extends CheckedInputStream {
  33.     private long remaining;
  34.     private final long expected;

  35.     /**
  36.      * Constructs a new instance.
  37.      *
  38.      * @param checksum         Checksum implementation.
  39.      * @param in               the stream to wrap
  40.      * @param size             the of the stream's content
  41.      * @param expectedChecksum the expected checksum
  42.      */
  43.     public ChecksumVerifyingInputStream(final Checksum checksum, final InputStream in, final long size, final long expectedChecksum) {
  44.         super(in, checksum);
  45.         this.expected = expectedChecksum;
  46.         this.remaining = size;
  47.     }

  48.     /**
  49.      * Gets the byte count remaining to read.
  50.      *
  51.      * @return bytes remaining to read.
  52.      * @since 1.21
  53.      */
  54.     public long getBytesRemaining() {
  55.         return remaining;
  56.     }

  57.     /**
  58.      * Reads a single byte from the stream
  59.      *
  60.      * @throws IOException if the underlying stream throws or the stream is exhausted and the Checksum doesn't match the expected value
  61.      */
  62.     @Override
  63.     public int read() throws IOException {
  64.         if (remaining <= 0) {
  65.             return -1;
  66.         }
  67.         final int data = super.read();
  68.         if (data >= 0) {
  69.             --remaining;
  70.         }
  71.         verify();
  72.         return data;
  73.     }

  74.     /**
  75.      * Reads from the stream into a byte array.
  76.      *
  77.      * @throws IOException if the underlying stream throws or the stream is exhausted and the Checksum doesn't match the expected value
  78.      */
  79.     @Override
  80.     public int read(final byte[] b, final int off, final int len) throws IOException {
  81.         if (len == 0) {
  82.             return 0;
  83.         }
  84.         final int readCount = super.read(b, off, len);
  85.         if (readCount >= 0) {
  86.             remaining -= readCount;
  87.         }
  88.         verify();
  89.         return readCount;
  90.     }

  91.     private void verify() throws IOException {
  92.         if (remaining <= 0 && expected != getChecksum().getValue()) {
  93.             throw new IOException("Checksum verification failed");
  94.         }
  95.     }
  96. }