Synchronize access to streams.

This commit is contained in:
Maschell 2018-12-06 16:45:01 +01:00
parent b0b678c851
commit 31becf6c8b

View File

@ -33,62 +33,66 @@ public final class StreamUtils {
} }
public static byte[] getBytesFromStream(InputStream in, int size) throws IOException { public static byte[] getBytesFromStream(InputStream in, int size) throws IOException {
byte[] result = new byte[size]; synchronized (in) {
byte[] buffer = new byte[0x8000]; byte[] result = new byte[size];
int totalRead = 0; byte[] buffer = new byte[0x8000];
do { int totalRead = 0;
int read = in.read(buffer); do {
if (read < 0) break; int read = in.read(buffer);
System.arraycopy(buffer, 0, result, totalRead, read); if (read < 0) break;
totalRead += read; System.arraycopy(buffer, 0, result, totalRead, read);
} while (totalRead < size); totalRead += read;
in.close(); } while (totalRead < size);
return result; in.close();
return result;
}
} }
public static int getChunkFromStream(InputStream inputStream, byte[] output, ByteArrayBuffer overflowbuffer, int BLOCKSIZE) throws IOException { public static int getChunkFromStream(InputStream inputStream, byte[] output, ByteArrayBuffer overflowbuffer, int BLOCKSIZE) throws IOException {
int bytesRead = -1; synchronized (inputStream) {
int inBlockBuffer = 0; int bytesRead = -1;
byte[] overflowbuf = overflowbuffer.getBuffer(); int inBlockBuffer = 0;
do { byte[] overflowbuf = overflowbuffer.getBuffer();
try { do {
bytesRead = inputStream.read(overflowbuf, overflowbuffer.getLengthOfDataInBuffer(), overflowbuffer.getSpaceLeft()); try {
bytesRead = inputStream.read(overflowbuf, overflowbuffer.getLengthOfDataInBuffer(), overflowbuffer.getSpaceLeft());
} catch (IOException e) { } catch (IOException e) {
log.info(e.getMessage()); log.info(e.getMessage());
if (!e.getMessage().equals("Write end dead")) { if (!e.getMessage().equals("Write end dead")) {
throw e; throw e;
} }
bytesRead = -1; bytesRead = -1;
}
if (bytesRead <= 0) {
if (overflowbuffer.getLengthOfDataInBuffer() > 0) {
System.arraycopy(overflowbuf, 0, output, 0, overflowbuffer.getLengthOfDataInBuffer());
inBlockBuffer = overflowbuffer.getLengthOfDataInBuffer();
} }
break; if (bytesRead <= 0) {
} if (overflowbuffer.getLengthOfDataInBuffer() > 0) {
System.arraycopy(overflowbuf, 0, output, 0, overflowbuffer.getLengthOfDataInBuffer());
inBlockBuffer = overflowbuffer.getLengthOfDataInBuffer();
}
overflowbuffer.addLengthOfDataInBuffer(bytesRead); break;
}
if (inBlockBuffer + overflowbuffer.getLengthOfDataInBuffer() > BLOCKSIZE) { overflowbuffer.addLengthOfDataInBuffer(bytesRead);
int tooMuch = (inBlockBuffer + bytesRead) - BLOCKSIZE;
int toRead = BLOCKSIZE - inBlockBuffer;
System.arraycopy(overflowbuf, 0, output, inBlockBuffer, toRead); if (inBlockBuffer + overflowbuffer.getLengthOfDataInBuffer() > BLOCKSIZE) {
inBlockBuffer += toRead; int tooMuch = (inBlockBuffer + bytesRead) - BLOCKSIZE;
int toRead = BLOCKSIZE - inBlockBuffer;
System.arraycopy(overflowbuf, toRead, overflowbuf, 0, tooMuch); System.arraycopy(overflowbuf, 0, output, inBlockBuffer, toRead);
overflowbuffer.setLengthOfDataInBuffer(tooMuch); inBlockBuffer += toRead;
} else {
System.arraycopy(overflowbuf, 0, output, inBlockBuffer, overflowbuffer.getLengthOfDataInBuffer()); System.arraycopy(overflowbuf, toRead, overflowbuf, 0, tooMuch);
inBlockBuffer += overflowbuffer.getLengthOfDataInBuffer(); overflowbuffer.setLengthOfDataInBuffer(tooMuch);
overflowbuffer.resetLengthOfDataInBuffer(); } else {
} System.arraycopy(overflowbuf, 0, output, inBlockBuffer, overflowbuffer.getLengthOfDataInBuffer());
} while (inBlockBuffer != BLOCKSIZE); inBlockBuffer += overflowbuffer.getLengthOfDataInBuffer();
return inBlockBuffer; overflowbuffer.resetLengthOfDataInBuffer();
}
} while (inBlockBuffer != BLOCKSIZE);
return inBlockBuffer;
}
} }
public static void saveInputStreamToOutputStream(InputStream inputStream, OutputStream outputStream, long filesize) throws IOException { public static void saveInputStreamToOutputStream(InputStream inputStream, OutputStream outputStream, long filesize) throws IOException {
@ -102,67 +106,73 @@ public final class StreamUtils {
public static void saveInputStreamToOutputStreamWithHash(InputStream inputStream, OutputStream outputStream, long filesize, byte[] hash, public static void saveInputStreamToOutputStreamWithHash(InputStream inputStream, OutputStream outputStream, long filesize, byte[] hash,
long expectedSizeForHash) throws IOException, CheckSumWrongException { long expectedSizeForHash) throws IOException, CheckSumWrongException {
MessageDigest sha1 = null; synchronized (inputStream) {
if (hash != null) {
try { MessageDigest sha1 = null;
sha1 = MessageDigest.getInstance("SHA1"); if (hash != null) {
} catch (NoSuchAlgorithmException e) { try {
e.printStackTrace(); sha1 = MessageDigest.getInstance("SHA1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
} }
int BUFFER_SIZE = 0x8000;
byte[] buffer = new byte[BUFFER_SIZE];
int read = 0;
long totalRead = 0;
long written = 0;
do {
read = inputStream.read(buffer);
if (read < 0) {
break;
}
totalRead += read;
if (totalRead > filesize) {
read = (int) (read - (totalRead - filesize));
}
outputStream.write(buffer, 0, read);
written += read;
if (sha1 != null) {
sha1.update(buffer, 0, read);
}
} while (written < filesize);
if (sha1 != null && hash != null) {
long missingInHash = expectedSizeForHash - written;
if (missingInHash > 0) {
sha1.update(new byte[(int) missingInHash]);
}
byte[] calculated_hash = sha1.digest();
byte[] expected_hash = hash;
if (!Arrays.equals(calculated_hash, expected_hash)) {
outputStream.close();
inputStream.close();
throw new CheckSumWrongException("Hash doesn't match saves output stream.", calculated_hash, expected_hash);
}
}
outputStream.close();
inputStream.close();
} }
int BUFFER_SIZE = 0x8000;
byte[] buffer = new byte[BUFFER_SIZE];
int read = 0;
long totalRead = 0;
long written = 0;
do {
read = inputStream.read(buffer);
if (read < 0) {
break;
}
totalRead += read;
if (totalRead > filesize) {
read = (int) (read - (totalRead - filesize));
}
outputStream.write(buffer, 0, read);
written += read;
if (sha1 != null) {
sha1.update(buffer, 0, read);
}
} while (written < filesize);
if (sha1 != null && hash != null) {
long missingInHash = expectedSizeForHash - written;
if (missingInHash > 0) {
sha1.update(new byte[(int) missingInHash]);
}
byte[] calculated_hash = sha1.digest();
byte[] expected_hash = hash;
if (!Arrays.equals(calculated_hash, expected_hash)) {
outputStream.close();
inputStream.close();
throw new CheckSumWrongException("Hash doesn't match saves output stream.", calculated_hash, expected_hash);
}
}
outputStream.close();
inputStream.close();
} }
public static void skipExactly(InputStream in, long offset) throws IOException { public static void skipExactly(InputStream in, long offset) throws IOException {
long n = offset; synchronized (in) {
while (n != 0) { long n = offset;
long skipped = in.skip(n); while (n != 0) {
if (skipped == 0) { long skipped = in.skip(n);
in.close(); if (skipped == 0) {
throw new EOFException(); in.close();
throw new EOFException();
}
n -= skipped;
} }
n -= skipped;
} }
} }
} }