/** * Prepares channel to write a 7z archive to. * * <p>{@link * org.apache.commons.compress.utils.SeekableInMemoryByteChannel} * allows you to write to an in-memory archive.</p> * * @param channel the channel to write to * @throws IOException if the channel cannot be positioned properly * @since 1.13 */ public SevenZOutputFile(final SeekableByteChannel channel) throws IOException { this.channel = channel; channel.position(SevenZFile.SIGNATURE_HEADER_SIZE); }
/** * Skips the given number of bytes or throws an EOFException if * skipping failed. */ private void skipBytes(final int count) throws IOException { long currentPosition = archive.position(); long newPosition = currentPosition + count; if (newPosition > archive.size()) { throw new EOFException(); } archive.position(newPosition); }
protected int read(long pos, ByteBuffer buf) throws IOException { int read; synchronized (archive) { archive.position(pos); read = archive.read(buf); } buf.flip(); return read; } }
/** * Checks whether the archive starts with a LFH. If it doesn't, * it may be an empty archive. */ private boolean startsWithLocalFileHeader() throws IOException { archive.position(0); wordBbuf.rewind(); IOUtils.readFully(archive, wordBbuf); return Arrays.equals(wordBuf, ZipArchiveOutputStream.LFH_SIG); }
List<Long> possibleOdexs = new ArrayList<>(); while (true) { long position = channel.position();
@ExpectWarning("OS_OPEN_STREAM") void test4(File f, byte b) throws IOException { SeekableByteChannel c = Files.newByteChannel(Paths.get(""), StandardOpenOption.APPEND); c.position(); }
@ExpectWarning("OS_OPEN_STREAM") void test3(File f, byte b) throws IOException { SeekableByteChannel c = Files.newByteChannel(Paths.get("")); c.position(); }
@Override public WorkUnit call() throws IOException { long pos = ((long) blockSize) * blockIndex; if (pos > chan.size()) { return this; } chan.position(pos); // read until buffer is full, or EOF while (chan.read(buf) > 0) {} ; return this; }
@Override public ByteBuffer call() throws IOException { long pos = ((long) blockSize) * blockIndex; if (pos > chan.size()) { return null; } if (pos < 0) { // This should never happen, if the code's correct. throw new IllegalArgumentException( "blockIndex " + blockIndex + " has position " + pos + ": negative position is not valid."); } chan.position(pos); // read until buffer is full, or EOF while (chan.read(buf) >= 0 && buf.hasRemaining()) {} return buf; }
channel.position(pos); head.position(0); int c = channel.read(head); channel.position(pos + dexOffset); copy(channel, channel2, copyBuff, fileSize); channel.position(pos + depsOffset); copy(channel, channel2, copyBuff, depsLength); channel.position(pos + optOffset); copy(channel, channel2, copyBuff, optLength);
/** * Searches for either the "Zip64 end of central directory * locator" or the "End of central dir record", parses * it and positions the stream at the first central directory * record. */ private void positionAtCentralDirectory() throws IOException { positionAtEndOfCentralDirectoryRecord(); boolean found = false; final boolean searchedForZip64EOCD = archive.position() > ZIP64_EOCDL_LENGTH; if (searchedForZip64EOCD) { archive.position(archive.position() - ZIP64_EOCDL_LENGTH); wordBbuf.rewind(); IOUtils.readFully(archive, wordBbuf); found = Arrays.equals(ZipArchiveOutputStream.ZIP64_EOCD_LOC_SIG, wordBuf); } if (!found) { // not a ZIP64 archive if (searchedForZip64EOCD) { skipBytes(ZIP64_EOCDL_LENGTH - WORD); } positionAtCentralDirectory32(); } else { positionAtCentralDirectory64(); } }
/** * Parses the "End of central dir record" and positions * the stream at the first central directory record. * * Expects stream to be positioned at the beginning of the * "End of central dir record". */ private void positionAtCentralDirectory32() throws IOException { skipBytes(CFD_LOCATOR_OFFSET); wordBbuf.rewind(); IOUtils.readFully(archive, wordBbuf); archive.position(ZipLong.getValue(wordBuf)); }
private void testSeeking(SeekableByteChannel chan1, SeekableByteChannel chan2, int position) throws IOException { ByteBuffer one = ByteBuffer.allocate(128); ByteBuffer two = ByteBuffer.allocate(128); chan1.position(position); chan2.position(position); readFully(chan1, one); readFully(chan2, two); assertThat(one.position()).isEqualTo(two.position()); assertThat(one.array()).isEqualTo(two.array()); }
/** * Parses the "Zip64 end of central directory locator", * finds the "Zip64 end of central directory record" using the * parsed information, parses that and positions the stream at the * first central directory record. * * Expects stream to be positioned right behind the "Zip64 * end of central directory locator"'s signature. */ private void positionAtCentralDirectory64() throws IOException { skipBytes(ZIP64_EOCDL_LOCATOR_OFFSET - WORD /* signature has already been read */); dwordBbuf.rewind(); IOUtils.readFully(archive, dwordBbuf); archive.position(ZipEightByteInteger.getLongValue(dwordBuf)); wordBbuf.rewind(); IOUtils.readFully(archive, wordBbuf); if (!Arrays.equals(wordBuf, ZipArchiveOutputStream.ZIP64_EOCD_SIG)) { throw new ZipException("archive's ZIP64 end of central " + "directory locator is corrupt."); } skipBytes(ZIP64_EOCD_CFD_LOCATOR_OFFSET - WORD /* signature has already been read */); dwordBbuf.rewind(); IOUtils.readFully(archive, dwordBbuf); archive.position(ZipEightByteInteger.getLongValue(dwordBuf)); }
private ByteBuffer readEncodedHeader(final ByteBuffer header, final Archive archive, final byte[] password) throws IOException { readStreamsInfo(header, archive); // FIXME: merge with buildDecodingStream()/buildDecoderStack() at some stage? final Folder folder = archive.folders[0]; final int firstPackStreamIndex = 0; final long folderOffset = SIGNATURE_HEADER_SIZE + archive.packPos + 0; channel.position(folderOffset); InputStream inputStreamStack = new BoundedSeekableByteChannelInputStream(channel, archive.packSizes[firstPackStreamIndex]); for (final Coder coder : folder.getOrderedCoders()) { if (coder.numInStreams != 1 || coder.numOutStreams != 1) { throw new IOException("Multi input/output stream coders are not yet supported"); } inputStreamStack = Coders.addDecoder(fileName, inputStreamStack, //NOSONAR folder.getUnpackSizeForCoder(coder), coder, password); } if (folder.hasCrc) { inputStreamStack = new CRC32VerifyingInputStream(inputStreamStack, folder.getUnpackSize(), folder.crc); } final byte[] nextHeader = new byte[(int)folder.getUnpackSize()]; try (DataInputStream nextHeaderInputStream = new DataInputStream(inputStreamStack)) { nextHeaderInputStream.readFully(nextHeader); } return ByteBuffer.wrap(nextHeader).order(ByteOrder.LITTLE_ENDIAN); }
@Test public void testNewByteChannelRead_seekBeyondSize_reportsEofOnNextRead() throws Exception { Path path = Paths.get(URI.create("gs://lol/cat")); Files.write(path, "hellocat".getBytes(UTF_8)); try (SeekableByteChannel input = Files.newByteChannel(path)) { ByteBuffer buffer = ByteBuffer.allocate(5); input.position(10); assertThat(input.read(buffer)).isEqualTo(-1); input.position(11); assertThat(input.read(buffer)).isEqualTo(-1); assertThat(input.size()).isEqualTo(8); } }
@Test public void testNewByteChannelRead_seeking() throws Exception { Path path = Paths.get(URI.create("gs://lol/cat")); Files.write(path, "helloworld".getBytes(UTF_8)); try (SeekableByteChannel input = Files.newByteChannel(path)) { ByteBuffer buffer = ByteBuffer.allocate(5); input.position(5); assertThat(input.position()).isEqualTo(5); assertThat(input.read(buffer)).isEqualTo(5); assertThat(input.position()).isEqualTo(10); assertThat(new String(buffer.array(), UTF_8)).isEqualTo("world"); buffer.rewind(); assertThat(input.read(buffer)).isEqualTo(-1); input.position(0); assertThat(input.position()).isEqualTo(0); assertThat(input.read(buffer)).isEqualTo(5); assertThat(input.position()).isEqualTo(5); assertThat(new String(buffer.array(), UTF_8)).isEqualTo("hello"); } }
@Test public void testNewByteChannelWrite() throws Exception { Path path = Paths.get(URI.create("gs://bucket/tests")); try (SeekableByteChannel output = Files.newByteChannel(path, WRITE)) { assertThat(output.position()).isEqualTo(0); assertThat(output.size()).isEqualTo(0); ByteBuffer buffer = ByteBuffer.wrap("filec".getBytes(UTF_8)); assertThat(output.write(buffer)).isEqualTo(5); assertThat(output.position()).isEqualTo(5); assertThat(output.size()).isEqualTo(5); buffer = ByteBuffer.wrap("onten".getBytes(UTF_8)); assertThat(output.write(buffer)).isEqualTo(5); assertThat(output.position()).isEqualTo(10); assertThat(output.size()).isEqualTo(10); } assertThat(new String(Files.readAllBytes(path), UTF_8)).isEqualTo("fileconten"); }
@Test(timeout = 60_000) public void testReadByteChannel() throws IOException { CloudStorageFileSystem testBucket = getTestBucket(); Path path = testBucket.getPath(SML_FILE); long size = Files.size(path); SeekableByteChannel chan = Files.newByteChannel(path, StandardOpenOption.READ); assertThat(chan.size()).isEqualTo(size); ByteBuffer buf = ByteBuffer.allocate(SML_SIZE); int read = 0; while (chan.isOpen()) { int rc = chan.read(buf); assertThat(chan.size()).isEqualTo(size); if (rc < 0) { // EOF break; } assertThat(rc).isGreaterThan(0); read += rc; assertThat(chan.position()).isEqualTo(read); } assertThat(read).isEqualTo(size); byte[] expected = new byte[SML_SIZE]; new Random(SML_SIZE).nextBytes(expected); assertThat(Arrays.equals(buf.array(), expected)).isTrue(); }
@Test public void testSeek() throws IOException { CloudStorageFileSystem testBucket = getTestBucket(); Path path = testBucket.getPath(BIG_FILE); int size = BIG_SIZE; byte[] contents = randomContents(size); byte[] sample = new byte[100]; byte[] wanted; byte[] wanted2; SeekableByteChannel chan = Files.newByteChannel(path, StandardOpenOption.READ); assertThat(chan.size()).isEqualTo(size); // check seek int dest = size / 2; chan.position(dest); readFully(chan, sample); wanted = Arrays.copyOfRange(contents, dest, dest + 100); assertThat(wanted).isEqualTo(sample); // now go back and check the beginning // (we do 2 locations because 0 is sometimes a special case). chan.position(0); readFully(chan, sample); wanted2 = Arrays.copyOf(contents, 100); assertThat(wanted2).isEqualTo(sample); // if the two spots in the file have the same contents, then this isn't a good file for this // test. assertThat(wanted).isNotEqualTo(wanted2); }