/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License 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 org.apache.pdfbox.io; import java.io.IOException; import junit.framework.TestCase; /** * This is a unit test for {@link RandomAccessBuffer}. * */ public class TestRandomAccessBuffer extends TestCase { private static final int CHUNK_SIZE = 1024; /** * This test checks two corner cases where the last read ends * exactly at the end of a chunck (remainingBytes == 0) * @throws IOException */ public void testRemainingByteZero() throws IOException { RandomAccessBuffer buffer = new RandomAccessBuffer(); byte[] byteArray = new byte[CHUNK_SIZE + 2]; // fill the second chunk with "1" for (int i = 0; i < 2; i++) { byteArray[CHUNK_SIZE + i] = 1; } buffer.write(byteArray); buffer.seek(CHUNK_SIZE - 2); // read the last bytes of the first chunk buffer.read(byteArray, 0, 2); // read the last 2 bytes of the buffer/the first bytes of the second chunk buffer.read(byteArray, 0, 2); // check the values read from the second chunk assertEquals(2, byteArray[0]+byteArray[1]); buffer.close(); buffer = new RandomAccessBuffer(); byteArray = new byte[2*CHUNK_SIZE + 2]; // fill the second chunk with "1" for (int i = 0; i < CHUNK_SIZE; i++) { byteArray[CHUNK_SIZE + i] = 1; } // fill the third chunk with "2" for (int i = 0; i < 2; i++) { byteArray[2*CHUNK_SIZE + i] = 2; } buffer.write(byteArray); buffer.seek(700); byte[] bytesRead = new byte[1348]; buffer.read(bytesRead, 0, bytesRead.length); assertEquals(2, buffer.read()); buffer.close(); } /** * Test the {@link RandomAccessBuffer#read()} * and {@link RandomAccessBuffer#write(int)} method. * * @throws IOException is thrown if something went wrong. */ public void testSimpleReadWrite() throws IOException { // create a buffer filled with 10 figures from 0 to 9 RandomAccessBuffer buffer = new RandomAccessBuffer(); for ( int i=0;i < 10;i++ ) { buffer.write(i); } // jump back to the beginning of the buffer buffer.seek(0); // sum up all figures, the result should be 45 int result = 0; for ( int i=0;i < 10;i++ ) { result += buffer.read(); } assertEquals(45, result); buffer.close(); } /** * Test the {@link RandomAccessBuffer#read(byte[], int, int)} * and {@link RandomAccessBuffer#write(byte[])} method. * * @throws IOException is thrown if something went wrong. */ public void testSimpleArrayReadWrite() throws IOException { // create an array filled with 10 figures from 0 to 9 byte[] byteArray = new byte[10]; for ( byte i=0;i < 10;i++ ) { byteArray[i] = i; } // create an empty buffer and write the array to it RandomAccessBuffer buffer = new RandomAccessBuffer(); buffer.write(byteArray); // jump back to the beginning of the buffer buffer.seek(0); // read the buffer byte after byte and sum up all figures, // the result should be 45 int result = 0; for ( int i=0;i < 10;i++ ) { result += buffer.read(); } assertEquals(45, result); // jump back to the beginning of the buffer buffer.seek(0); // read the buffer to an array and sum up all figures, // the result should be 45 buffer.read(byteArray, 0, byteArray.length); result = 0; for ( int i=0;i < 10;i++ ) { result += byteArray[i]; } assertEquals(45, result); buffer.close(); } /** * Test the {@link RandomAccessBuffer#read(byte[], int, int)} * and {@link RandomAccessBuffer#write(byte[])} method using * a couple of data to create more than one chunk. * * @throws IOException is thrown if something went wrong. */ public void testArrayReadWrite() throws IOException { // create an array filled with 1024 * "0", 1024 * "1" and 100 * "2" byte[] byteArray = new byte[ 2 * CHUNK_SIZE + 100]; for (int i = CHUNK_SIZE;i < 2 * CHUNK_SIZE; i++) { byteArray[i] = 1; } for (int i = 2 * CHUNK_SIZE; i < 2 * CHUNK_SIZE + 100; i++) { byteArray[i] = 2; } // write the array to a buffer RandomAccessBuffer buffer = new RandomAccessBuffer(); buffer.write(byteArray); // jump to the beginning buffer.seek(0); // the first byte should be "0" assertEquals(0, buffer.read()); // jump to the last byte of the first chunk, it should be "0" buffer.seek(CHUNK_SIZE - 1); assertEquals(0, buffer.read()); // jump to the first byte of the second chunk, it should be "1" buffer.seek(CHUNK_SIZE); assertEquals(1, buffer.read()); // jump to the end-5 of the first chunk buffer.seek(CHUNK_SIZE - 5); // read the last 5 bytes from the first and the first 5 bytes // from the second chunk and sum them up. The result should be "5" byteArray = new byte[10]; buffer.read(byteArray,0, byteArray.length); int result = 0; for ( int i=0;i < 10;i++ ) { result += byteArray[i]; } assertEquals(5, result); // jump to the end-5 of the second chunk buffer.seek(2 * CHUNK_SIZE - 5); // read the last 5 bytes from the second and the first 5 bytes // from the third chunk and sum them up. The result should be "15" byteArray = new byte[10]; buffer.read(byteArray); result = 0; for ( int i=0;i < 10;i++ ) { result += byteArray[i]; } assertEquals(15, result); buffer.close(); } /** * Test if overwriting works. * * @throws IOException is thrown if something went wrong. */ public void testOverwrite() throws IOException { // create a buffer filled with 1024 * "0" and 100 * "1" byte[] byteArray = new byte[ CHUNK_SIZE + 100]; RandomAccessBuffer buffer = new RandomAccessBuffer(); for (int i = CHUNK_SIZE;i < CHUNK_SIZE + 100; i++) { byteArray[i] = 1; } buffer.write(byteArray); // jump to the end-5 of the first chunk buffer.seek(CHUNK_SIZE - 5); // read the last 5 bytes from the first and the first 5 bytes // from the second chunk and sum them up. The result should be "5" byteArray = new byte[10]; buffer.read(byteArray,0, byteArray.length); int result = 0; for ( int i=0;i < 10;i++ ) { result += byteArray[i]; } assertEquals(5, result); // jump to the end-5 of the first chunk buffer.seek(CHUNK_SIZE - 5); // write 5 "2" and 5 "3" to the buffer for ( int i=0;i < 5;i++ ) { buffer.write(2); } for ( int i=0;i < 5;i++ ) { buffer.write(3); } // jump to the end-5 of the first chunk buffer.seek(CHUNK_SIZE - 5); // read the last 5 bytes from the first and the first 5 bytes // from the second chunk and sum them up. The result should be "25" byteArray = new byte[10]; buffer.read(byteArray,0, byteArray.length); result = 0; for ( int i=0;i < 10;i++ ) { result += byteArray[i]; } assertEquals(25, result); buffer.close(); } /** * Test if seeking beyond EOF works. * * @throws IOException is thrown if something went wrong. */ public void testSeekBeyondEOF() throws IOException { // create a buffer filled with 10 figures from 0 to 9 RandomAccessBuffer buffer = new RandomAccessBuffer(); for ( int i=0;i < 10;i++ ) { buffer.write(i); } // jump back to the beginning of the buffer buffer.seek(0); // jump beyond EOF buffer.seek(20); // try to read assertEquals(-1, buffer.read()); // check EOF assertTrue(buffer.isEOF()); buffer.close(); } public void testPDFBOX1490() throws Exception { // create a buffer filled with 1024 * "0" byte[] byteArray = new byte[ CHUNK_SIZE-1]; RandomAccessBuffer buffer = new RandomAccessBuffer(); buffer.write(byteArray); // fill the first buffer until the end buffer.write(0); // seek the current == last position in the first buffer chunk buffer.seek(buffer.getPosition()); buffer.close(); } public void testPDFBOX2969() throws Exception { // create buffer with non-default chunk size // by providing an array with unusual size // (larger than RandomAccessBuffer.DEFAULT_CHUNK_SIZE) int chunkSize = (CHUNK_SIZE << 4) + 3; byte[] byteArray = new byte[chunkSize]; RandomAccessBuffer buffer = new RandomAccessBuffer(byteArray); // fill completely for (int i = 0; i < chunkSize; i++) { buffer.write(1); } // create clone RandomAccessBuffer bufferClone = buffer.clone(); // read all from both buffer.seek(0); int bufRead = buffer.read(new byte[(int)buffer.length()]); bufferClone.seek(0); int bufCloneRead = bufferClone.read(new byte[(int)bufferClone.length()]); assertEquals(bufRead, bufCloneRead); buffer.close(); bufferClone.close(); } }