}
// We need to know how big the object is to download it. Fail the
// transfer if we can't determine the object size.
if (this.totalBytes == -1) {
throw new EsuException("Failed to get object size");
}
if( checksumming ) {
try {
checksum = new Checksum( Algorithm.SHA0 );
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException( "Could not initialize SHA0 hash algorithm" );
}
}
// Loop, downloading chunks until the transfer is complete.
while (true) {
try {
Extent extent = null;
// Determine how much data to download. If we're at the last
// request in the transfer, only request as many bytes as needed
// to get to the end of the file.
if (currentBytes + buffer.getBuffer().length > totalBytes) {
// Would go past end of file. Request less bytes.
extent = new Extent(this.currentBytes, totalBytes
- currentBytes);
} else {
extent = new Extent(this.currentBytes,
buffer.getBuffer().length);
}
buffer.setSize((int) extent.getSize());
// Read data from the server.
byte[] obuffer = this.esu.readObject(id, extent, buffer.getBuffer(), checksum);
// See if they returned the buffer we're using. In some
// cases, this doesn't happen (when content length is not
// defined in the response).
if( obuffer != buffer.getBuffer() ) {
if( obuffer.length != extent.getSize() ) {
throw new EsuException( "Read size mismatch. " +
"Requested " + extent.getSize() +
" bytes but received " +
obuffer.length + " bytes" );
}
stream.write( obuffer, 0, obuffer.length );
} else {
// Write to the stream
stream.write(buffer.getBuffer(), buffer.getOffset(), buffer
.getSize());
}
// Update progress
this.progress(buffer.getSize());
// See if we're done.
if (this.currentBytes == this.totalBytes) {
if( checksumming && checksum.getExpectedValue() != null ) {
// Validate
if( !checksum.getExpectedValue().equals( checksum.toString() ) ) {
throw new EsuException("Checksum validation error. Expected " + checksum.getExpectedValue() + " but computed " + checksum.toString() );
} else {
l4j.info( "Checksum OK: " + checksum.getExpectedValue() );
}
}
this.complete();
return;
}
} catch (EsuException e) {
this.fail(e);
throw e;
} catch (IOException e) {
fail(e);
throw new EsuException("Error downloading file", e);
}
}
}