
com.amazonaws.util.LengthCheckInputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-java-sdk-osgi Show documentation
Show all versions of aws-java-sdk-osgi Show documentation
The AWS SDK for Java with support for OSGi. The AWS SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).
/*
* Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.amazonaws.util;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.annotation.NotThreadSafe;
import com.amazonaws.AmazonClientException;
import com.amazonaws.internal.SdkFilterInputStream;
/**
* Used to perform length check to ensure the number of bytes read from the
* underlying input stream is the same as the expected total.
*/
@NotThreadSafe
public class LengthCheckInputStream extends SdkFilterInputStream {
public static final boolean INCLUDE_SKIPPED_BYTES = true;
public static final boolean EXCLUDE_SKIPPED_BYTES = false;
/**
* Total number of bytes expected to be read from the underlying input
* stream.
*/
private final long expectedLength;
/**
* True if skipped bytes are to be included as part of the data length;
* false otherwise.
*/
private final boolean includeSkipped;
/**
* The length of the data read from the underlying input stream so far.
*/
private long dataLength;
private long marked; // used for mark-and-reset purposes
/**
* Used for diagnostic purposes. True if reset has been called since last
* marked; False otherwise.
*/
private boolean resetSinceLastMarked;
private int markCount, resetCount;
/**
* Constructs an input stream that performs length check to ensure the
* number of bytes read from the underlying input stream is the same as the
* expected total.
*
* @param in
* the underlying input stream
* @param expectedLength
* the total length of the data in bytes expected to be read from
* the underlying input stream; must be non-negative.
* @param includeSkipped
* true if bytes skipped are to be considered as part of the data
* length; false otherwise. Typically, this parameter should be
* set to false for uploading data to AWS, but set to true for
* receiving data from AWS.
*/
public LengthCheckInputStream(InputStream in, long expectedLength,
boolean includeSkipped) {
super(in);
if (expectedLength < 0)
throw new IllegalArgumentException();
this.expectedLength = expectedLength;
this.includeSkipped = includeSkipped;
}
/**
* {@inheritDoc}
*
* @throws AmazonClientException
* if the data length read has exceeded the expected total, or
* if the total data length is not the same as the expected
* total.
*/
@Override
public int read() throws IOException {
final int c = super.read();
if (c >= 0)
dataLength++;
checkLength(c == -1);
return c;
}
/**
* {@inheritDoc}
*
* @throws AmazonClientException
* if the data length read has exceeded the expected total, or
* if the total data length is not the same as the expected
* total.
*/
@Override
public int read(byte[] b, int off, int len) throws IOException {
int readLen = super.read(b, off, len);
dataLength += readLen >= 0 ? readLen : 0;
checkLength(readLen == -1);
return readLen;
}
@Override
public void mark(int readlimit) {
if (markSupported()) {
super.mark(readlimit);
marked = dataLength;
markCount++;
resetSinceLastMarked = false;
}
}
@Override
public void reset() throws IOException {
if (markSupported()) {
super.reset();
dataLength = marked;
resetCount++;
resetSinceLastMarked = true;
} else {
throw new IOException("mark/reset not supported");
}
}
/**
* Checks the data length read so far against the expected total.
*
* @param eof
* true if end of stream has been encountered; false otherwise
*
* @throws AmazonClientException
* if the data length read has exceeded the expected total, or
* if the total data length is not the same as the expected
* total.
*/
private void checkLength(boolean eof) {
if (eof) {
if (dataLength != expectedLength) {
throw new AmazonClientException(
"Data read has a different length than the expected: "
+ diagnosticInfo());
}
} else if (dataLength > expectedLength) {
throw new AmazonClientException("More data read than expected: "
+ diagnosticInfo());
}
}
private String diagnosticInfo() {
return new StringBuilder()
.append("dataLength=").append(dataLength)
.append("; expectedLength=").append(expectedLength)
.append("; includeSkipped=").append(includeSkipped)
.append("; in.getClass()=").append(in.getClass())
.append("; markedSupported=").append(markSupported())
.append("; marked=").append(marked)
.append("; resetSinceLastMarked=").append(resetSinceLastMarked)
.append("; markCount=").append(markCount)
.append("; resetCount=").append(resetCount)
.toString();
}
/**
* {@inheritDoc}
*
* @throws AmazonClientException
* if {@link #includeSkipped} is true and the data length
* skipped has exceeded the expected total.
*/
@Override
public long skip(long n) throws IOException {
final long skipped = super.skip(n);
if (includeSkipped && skipped > 0) {
dataLength += skipped;
checkLength(false);
}
return skipped;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy