ChecksumVerifyingInputStream.java

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

  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.util.zip.CheckedInputStream;
  21. import java.util.zip.Checksum;

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

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

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

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

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

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