BsPatch { static void readFully( final InputStream in, final byte[] destination, final int startAt, final int numBytes) throws IOException { int numRead = 0; while (numRead < numBytes) { int readNow = in.read(destination, startAt + numRead, numBytes - numRead); if (readNow == -1) { throw new IOException("truncated input stream"); } numRead += readNow; } }  static void applyPatch(
      RandomAccessFile oldData, OutputStream newData, InputStream patchData); static void applyPatch(
      RandomAccessFile oldData, OutputStream newData, InputStream patchData, Long expectedNewSize);  }
@Test public void testReadFully() throws IOException { final byte[] input = "this is a sample string to read".getBytes("UTF-8"); final ByteArrayInputStream inputStream = new ByteArrayInputStream(input); final byte[] dst = new byte[50]; try { BsPatch.readFully(inputStream, dst, 0, 50); Assert.fail("Should've thrown an IOException"); } catch (IOException expected) { } inputStream.reset(); BsPatch.readFully(inputStream, dst, 0, input.length); Assert.assertTrue(regionEquals(dst, 0, input, 0, input.length)); inputStream.reset(); BsPatch.readFully(inputStream, dst, 40, 10); Assert.assertTrue(regionEquals(dst, 40, input, 0, 10)); inputStream.reset(); try { BsPatch.readFully(inputStream, dst, 45, 11); Assert.fail("Should've thrown an IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException expected) { } }