Oops, since this JIRA is assigned to me, and I've found no objection there.I thought you are polite to wait for me to commit it. (Obviously, I was wrong. :-)
+1 for the Tim proposed (which is committed by me) patch. If anyone has any other thoughts, I can revert it back. 2008/11/28 Tim Ellison <[EMAIL PROTECTED]> > Hmm, I'm surprised that you committed my patch Sean -- I could have done > it myself if I'd thought we were done with the discussion. > > So did we conclude that the problems inherent in this version are any > better than the problems in the original version? > > In summary, > - the original code synchronized on close(), unlike the RI. Its safe, > but can cause potential deadlock if people rely on the unspecified RI > behavior. > - the proposed (erm, committed ;-) patch is unsynchronized, but now has > a race condition (see the FIXME comment) which could miss the close. > > Regards, > Tim > > [EMAIL PROTECTED] wrote: > > Author: qiuxx > > Date: Wed Nov 26 19:24:37 2008 > > New Revision: 721075 > > > > URL: http://svn.apache.org/viewvc?rev=721075&view=rev > > Log: > > Apply for HARMONY-6014,([classlib][luni] BufferedInputStream can not be > closed in another thread) > > > > Modified: > > > harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/BufferedInputStream.java > > > harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/BufferedInputStreamTest.java > > > > Modified: > harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/BufferedInputStream.java > > URL: > http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/BufferedInputStream.java?rev=721075&r1=721074&r2=721075&view=diff > > > ============================================================================== > > --- > harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/BufferedInputStream.java > (original) > > +++ > harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/BufferedInputStream.java > Wed Nov 26 19:24:37 2008 > > @@ -21,8 +21,8 @@ > > > > /** > > * <code>BufferedInputStream</code> is a class which takes an input > stream and > > - * <em>buffers</em> the input. In this way, costly interaction with the > > - * original input stream can be minimized by reading buffered amounts of > data > > + * <em>buffers</em> the input. In this way, costly interaction with the > original > > + * input stream can be minimized by reading buffered amounts of data > > * infrequently. The drawback is that extra space is required to hold > the buffer > > * and that copying takes place when reading that buffer. > > * > > @@ -32,7 +32,7 @@ > > /** > > * The buffer containing the current bytes read from the target > InputStream. > > */ > > - protected byte[] buf; > > + protected volatile byte[] buf; > > > > /** > > * The total number of bytes inside the byte array <code>buf</code>. > > @@ -55,12 +55,10 @@ > > */ > > protected int pos; > > > > - private boolean closed = false; > > - > > /** > > * Constructs a new <code>BufferedInputStream</code> on the > InputStream > > - * <code>in</code>. The default buffer size (8Kb) is allocated and > all > > - * reads can now be filtered through this stream. > > + * <code>in</code>. The default buffer size (8Kb) is allocated and > all reads > > + * can now be filtered through this stream. > > * > > * @param in > > * the InputStream to buffer reads on. > > @@ -101,11 +99,12 @@ > > */ > > @Override > > public synchronized int available() throws IOException { > > - if (buf == null) { > > + InputStream localIn = in; // 'in' could be invalidated by > close() > > + if (buf == null || localIn == null) { > > // K0059=Stream is closed > > throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$ > > } > > - return count - pos + in.available(); > > + return count - pos + localIn.available(); > > } > > > > /** > > @@ -116,19 +115,20 @@ > > * If an error occurs attempting to close this stream. > > */ > > @Override > > - public synchronized void close() throws IOException { > > - if (null != in) { > > - super.close(); > > - in = null; > > - } > > + public void close() throws IOException { > > buf = null; > > - closed = true; > > + InputStream localIn = in; > > + in = null; > > + if (localIn != null) { > > + localIn.close(); > > + } > > } > > > > - private int fillbuf() throws IOException { > > + private int fillbuf(InputStream localIn, byte[] localBuf) > > + throws IOException { > > if (markpos == -1 || (pos - markpos >= marklimit)) { > > /* Mark position not set or exceeded readlimit */ > > - int result = in.read(buf); > > + int result = localIn.read(localBuf); > > if (result > 0) { > > markpos = -1; > > pos = 0; > > @@ -136,32 +136,35 @@ > > } > > return result; > > } > > - if (markpos == 0 && marklimit > buf.length) { > > - /* Increase buffer size to accomodate the readlimit */ > > - int newLength = buf.length * 2; > > + if (markpos == 0 && marklimit > localBuf.length) { > > + /* Increase buffer size to accommodate the readlimit */ > > + int newLength = localBuf.length * 2; > > if (newLength > marklimit) { > > newLength = marklimit; > > } > > byte[] newbuf = new byte[newLength]; > > - System.arraycopy(buf, 0, newbuf, 0, buf.length); > > - buf = newbuf; > > + System.arraycopy(localBuf, 0, newbuf, 0, localBuf.length); > > + // Reassign buf, which will invalidate any local references > > + // FIXME: what if buf was null? > > + localBuf = buf = newbuf; > > } else if (markpos > 0) { > > - System.arraycopy(buf, markpos, buf, 0, buf.length - > markpos); > > + System.arraycopy(localBuf, markpos, localBuf, 0, > localBuf.length > > + - markpos); > > } > > /* Set the new position and mark position */ > > pos -= markpos; > > count = markpos = 0; > > - int bytesread = in.read(buf, pos, buf.length - pos); > > + int bytesread = localIn.read(localBuf, pos, localBuf.length - > pos); > > count = bytesread <= 0 ? pos : pos + bytesread; > > return bytesread; > > } > > > > /** > > * Set a Mark position in this BufferedInputStream. The parameter > > - * <code>readLimit</code> indicates how many bytes can be read > before a > > - * mark is invalidated. Sending reset() will reposition the Stream > back to > > - * the marked position provided <code>readLimit</code> has not been > > - * surpassed. The underlying buffer may be increased in size to > allow > > + * <code>readLimit</code> indicates how many bytes can be read > before a mark > > + * is invalidated. Sending reset() will reposition the Stream back > to the > > + * marked position provided <code>readLimit</code> has not been > surpassed. > > + * The underlying buffer may be increased in size to allow > > * <code>readlimit</code> number of bytes to be supported. > > * > > * @param readlimit > > @@ -200,28 +203,40 @@ > > */ > > @Override > > public synchronized int read() throws IOException { > > - if (in == null) { > > + // Use local refs since buf and in may be invalidated by an > > + // unsynchronized close() > > + byte[] localBuf = buf; > > + InputStream localIn = in; > > + if (localBuf == null || localIn == null) { > > // K0059=Stream is closed > > throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$ > > } > > > > /* Are there buffered bytes available? */ > > - if (pos >= count && fillbuf() == -1) { > > + if (pos >= count && fillbuf(localIn, localBuf) == -1) { > > return -1; /* no, fill buffer */ > > } > > + // localBuf may have been invalidated by fillbuf > > + if (localBuf != buf) { > > + localBuf = buf; > > + if (localBuf == null) { > > + // K0059=Stream is closed > > + throw new IOException(Msg.getString("K0059")); > //$NON-NLS-1$ > > + } > > + } > > > > /* Did filling the buffer fail with -1 (EOF)? */ > > if (count - pos > 0) { > > - return buf[pos++] & 0xFF; > > + return localBuf[pos++] & 0xFF; > > } > > return -1; > > } > > > > /** > > - * Reads at most <code>length</code> bytes from this > BufferedInputStream > > - * and stores them in byte array <code>buffer</code> starting at > offset > > - * <code>offset</code>. Answer the number of bytes actually read or > -1 if > > - * no bytes were read and end of stream was encountered. If all the > buffered > > + * Reads at most <code>length</code> bytes from this > BufferedInputStream and > > + * stores them in byte array <code>buffer</code> starting at offset > > + * <code>offset</code>. Answer the number of bytes actually read or > -1 if no > > + * bytes were read and end of stream was encountered. If all the > buffered > > * bytes have been used, a mark has not been set, and the requested > number > > * of bytes is larger than the receiver's buffer size, this > implementation > > * bypasses the buffer and simply places the results directly into > > @@ -242,7 +257,10 @@ > > @Override > > public synchronized int read(byte[] buffer, int offset, int length) > > throws IOException { > > - if (closed) { > > + // Use local ref since buf may be invalidated by an > unsynchronized > > + // close() > > + byte[] localBuf = buf; > > + if (localBuf == null) { > > // K0059=Stream is closed > > throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$ > > } > > @@ -253,7 +271,9 @@ > > if (length == 0) { > > return 0; > > } > > - if (null == buf) { > > + InputStream localIn = in; > > + if (localIn == null) { > > + // K0059=Stream is closed > > throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$ > > } > > > > @@ -261,9 +281,9 @@ > > if (pos < count) { > > /* There are bytes available in the buffer. */ > > int copylength = count - pos >= length ? length : count - > pos; > > - System.arraycopy(buf, pos, buffer, offset, copylength); > > + System.arraycopy(localBuf, pos, buffer, offset, copylength); > > pos += copylength; > > - if (copylength == length || in.available() == 0) { > > + if (copylength == length || localIn.available() == 0) { > > return copylength; > > } > > offset += copylength; > > @@ -278,24 +298,33 @@ > > * If we're not marked and the required size is greater than > the > > * buffer, simply read the bytes directly bypassing the > buffer. > > */ > > - if (markpos == -1 && required >= buf.length) { > > - read = in.read(buffer, offset, required); > > + if (markpos == -1 && required >= localBuf.length) { > > + read = localIn.read(buffer, offset, required); > > if (read == -1) { > > return required == length ? -1 : length - required; > > } > > } else { > > - if (fillbuf() == -1) { > > + if (fillbuf(localIn, localBuf) == -1) { > > return required == length ? -1 : length - required; > > } > > + // localBuf may have been invalidated by fillbuf > > + if (localBuf != buf) { > > + localBuf = buf; > > + if (localBuf == null) { > > + // K0059=Stream is closed > > + throw new IOException(Msg.getString("K0059")); > //$NON-NLS-1$ > > + } > > + } > > + > > read = count - pos >= required ? required : count - pos; > > - System.arraycopy(buf, pos, buffer, offset, read); > > + System.arraycopy(localBuf, pos, buffer, offset, read); > > pos += read; > > } > > required -= read; > > if (required == 0) { > > return length; > > } > > - if (in.available() == 0) { > > + if (localIn.available() == 0) { > > return length - required; > > } > > offset += read; > > @@ -304,18 +333,16 @@ > > > > /** > > * Reset this BufferedInputStream to the last marked location. If > the > > - * <code>readlimit</code> has been passed or no <code>mark</code> > has > > - * been set, throw IOException. This implementation resets the > target > > - * stream. > > + * <code>readlimit</code> has been passed or no <code>mark</code> > has been > > + * set, throw IOException. This implementation resets the target > stream. > > * > > * @throws IOException > > * If the stream is already closed or another > IOException > > * occurs. > > */ > > - > > @Override > > public synchronized void reset() throws IOException { > > - if (closed) { > > + if (buf == null) { > > // K0059=Stream is closed > > throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$ > > } > > @@ -341,7 +368,11 @@ > > */ > > @Override > > public synchronized long skip(long amount) throws IOException { > > - if (null == in) { > > + // Use local refs since buf and in may be invalidated by an > > + // unsynchronized close() > > + byte[] localBuf = buf; > > + InputStream localIn = in; > > + if (localBuf == null || localIn == null) { > > // K0059=Stream is closed > > throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$ > > } > > @@ -358,7 +389,7 @@ > > > > if (markpos != -1) { > > if (amount <= marklimit) { > > - if (fillbuf() == -1) { > > + if (fillbuf(localIn, localBuf) == -1) { > > return read; > > } > > if (count - pos >= amount - read) { > > @@ -372,6 +403,6 @@ > > } > > markpos = -1; > > } > > - return read + in.skip(amount - read); > > + return read + localIn.skip(amount - read); > > } > > } > > > > Modified: > harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/BufferedInputStreamTest.java > > URL: > http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/BufferedInputStreamTest.java?rev=721075&r1=721074&r2=721075&view=diff > > > ============================================================================== > > --- > harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/BufferedInputStreamTest.java > (original) > > +++ > harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/BufferedInputStreamTest.java > Wed Nov 26 19:24:37 2008 > > @@ -1,443 +1,489 @@ > > -/* > > - * 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.harmony.luni.tests.java.io; > > - > > -import java.io.BufferedInputStream; > > -import java.io.ByteArrayInputStream; > > -import java.io.File; > > -import java.io.FileInputStream; > > -import java.io.FileOutputStream; > > -import java.io.IOException; > > -import java.io.InputStream; > > -import java.io.OutputStream; > > -import junit.framework.TestCase; > > -import tests.support.Support_PlatformFile; > > - > > -public class BufferedInputStreamTest extends TestCase { > > - > > - public String fileName; > > - > > - private BufferedInputStream is; > > - > > - private FileInputStream isFile; > > - > > - byte[] ibuf = new byte[4096]; > > - > > - public String fileString = > "Test_All_Tests\nTest_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang > _Cl > > > > assNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_la > ng_ > > > > Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_S > ock > > > > etException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n"; > > - > > - /* > > - * @tests java.io.BufferedInputStream(InputStream) > > - */ > > - public void test_ConstructorLjava_io_InputStream() { > > - try { > > - BufferedInputStream str = new BufferedInputStream(null); > > - str.read(); > > - fail("Expected an IOException"); > > - } catch (IOException e) { > > - // Expected > > - } > > - } > > - > > - /* > > - * @tests java.io.BufferedInputStream(InputStream) > > - */ > > - public void test_ConstructorLjava_io_InputStreamI() throws > IOException { > > - try { > > - BufferedInputStream str = new BufferedInputStream(null, 1); > > - str.read(); > > - fail("Expected an IOException"); > > - } catch (IOException e) { > > - // Expected > > - } > > - > > - // Test for method > java.io.BufferedInputStream(java.io.InputStream, int) > > - > > - // Create buffer with exact size of file > > - is = new BufferedInputStream(isFile, this.fileString.length()); > > - // Ensure buffer gets filled by evaluating one read > > - is.read(); > > - // Close underlying FileInputStream, all but 1 buffered bytes > should > > - // still be available. > > - isFile.close(); > > - // Read the remaining buffered characters, no IOException should > > - // occur. > > - is.skip(this.fileString.length() - 2); > > - is.read(); > > - try { > > - // is.read should now throw an exception because it will > have to > > - // be filled. > > - is.read(); > > - fail("Exception should have been triggered by read()"); > > - } catch (IOException e) { > > - // Expected > > - } > > - > > - // regression test for harmony-2407 > > - new MockBufferedInputStream(null); > > - assertNotNull(MockBufferedInputStream.buf); > > - MockBufferedInputStream.buf = null; > > - new MockBufferedInputStream(null, 100); > > - assertNotNull(MockBufferedInputStream.buf); > > - } > > - > > - static class MockBufferedInputStream extends BufferedInputStream { > > - static byte[] buf; > > - > > - MockBufferedInputStream(InputStream is) throws IOException { > > - super(is); > > - buf = super.buf; > > - } > > - > > - MockBufferedInputStream(InputStream is, int size) throws > IOException { > > - super(is, size); > > - buf = super.buf; > > - } > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#available() > > - */ > > - public void test_available() throws IOException { > > - assertTrue("Returned incorrect number of available bytes", is > > - .available() == fileString.length()); > > - > > - // Test that a closed stream throws an IOE for available() > > - BufferedInputStream bis = new BufferedInputStream( > > - new ByteArrayInputStream(new byte[] { 'h', 'e', 'l', > 'l', 'o', > > - ' ', 't', 'i', 'm' })); > > - int available = bis.available(); > > - bis.close(); > > - assertTrue(available != 0); > > - > > - try { > > - bis.available(); > > - fail("Expected test to throw IOE."); > > - } catch (IOException ex) { > > - // expected > > - } > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#close() > > - */ > > - public void test_close() throws IOException { > > - new BufferedInputStream(isFile).close(); > > - > > - // regression for HARMONY-667 > > - BufferedInputStream buf = new BufferedInputStream(null, 5); > > - buf.close(); > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#mark(int) > > - */ > > - public void test_markI() throws IOException { > > - byte[] buf1 = new byte[100]; > > - byte[] buf2 = new byte[100]; > > - is.skip(3000); > > - is.mark(1000); > > - is.read(buf1, 0, buf1.length); > > - is.reset(); > > - is.read(buf2, 0, buf2.length); > > - is.reset(); > > - assertTrue("Failed to mark correct position", new String(buf1, > 0, > > - buf1.length).equals(new String(buf2, 0, buf2.length))); > > - > > - byte[] bytes = new byte[256]; > > - for (int i = 0; i < 256; i++) { > > - bytes[i] = (byte) i; > > - } > > - InputStream in = new BufferedInputStream( > > - new ByteArrayInputStream(bytes), 12); > > - in.skip(6); > > - in.mark(14); > > - in.read(new byte[14], 0, 14); > > - in.reset(); > > - assertTrue("Wrong bytes", in.read() == 6 && in.read() == 7); > > - > > - in = new BufferedInputStream(new ByteArrayInputStream(bytes), > 12); > > - in.skip(6); > > - in.mark(8); > > - in.skip(7); > > - in.reset(); > > - assertTrue("Wrong bytes 2", in.read() == 6 && in.read() == 7); > > - > > - BufferedInputStream buf = new BufferedInputStream( > > - new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4 }), > 2); > > - buf.mark(3); > > - bytes = new byte[3]; > > - int result = buf.read(bytes); > > - assertEquals(3, result); > > - assertEquals("Assert 0:", 0, bytes[0]); > > - assertEquals("Assert 1:", 1, bytes[1]); > > - assertEquals("Assert 2:", 2, bytes[2]); > > - assertEquals("Assert 3:", 3, buf.read()); > > - > > - buf = new BufferedInputStream(new ByteArrayInputStream(new > byte[] { 0, > > - 1, 2, 3, 4 }), 2); > > - buf.mark(3); > > - bytes = new byte[4]; > > - result = buf.read(bytes); > > - assertEquals(4, result); > > - assertEquals("Assert 4:", 0, bytes[0]); > > - assertEquals("Assert 5:", 1, bytes[1]); > > - assertEquals("Assert 6:", 2, bytes[2]); > > - assertEquals("Assert 7:", 3, bytes[3]); > > - assertEquals("Assert 8:", 4, buf.read()); > > - assertEquals("Assert 9:", -1, buf.read()); > > - > > - buf = new BufferedInputStream(new ByteArrayInputStream(new > byte[] { 0, > > - 1, 2, 3, 4 }), 2); > > - buf.mark(Integer.MAX_VALUE); > > - buf.read(); > > - buf.close(); > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#markSupported() > > - */ > > - public void test_markSupported() { > > - assertTrue("markSupported returned incorrect value", > is.markSupported()); > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#read() > > - */ > > - public void test_read() throws IOException { > > - int c = is.read(); > > - assertTrue("read returned incorrect char", c == > fileString.charAt(0)); > > - > > - byte[] bytes = new byte[256]; > > - for (int i = 0; i < 256; i++) { > > - bytes[i] = (byte) i; > > - } > > - InputStream in = new BufferedInputStream( > > - new ByteArrayInputStream(bytes), 12); > > - assertEquals("Wrong initial byte", 0, in.read()); // Fill the > > - // buffer > > - byte[] buf = new byte[14]; > > - in.read(buf, 0, 14); // Read greater than the buffer > > - assertTrue("Wrong block read data", new String(buf, 0, 14) > > - .equals(new String(bytes, 1, 14))); > > - assertEquals("Wrong bytes", 15, in.read()); // Check next byte > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#read(byte[], int, int) > > - */ > > - public void test_read$BII_Exception() throws IOException { > > - BufferedInputStream bis = new BufferedInputStream(null); > > - try { > > - bis.read(null, -1, -1); > > - fail("should throw NullPointerException"); > > - } catch (NullPointerException e) { > > - // expected > > - } > > - > > - try { > > - bis.read(new byte[0], -1, -1); > > - fail("should throw IndexOutOfBoundsException"); > > - } catch (IndexOutOfBoundsException e) { > > - // expected > > - } > > - > > - try { > > - bis.read(new byte[0], 1, -1); > > - fail("should throw IndexOutOfBoundsException"); > > - } catch (IndexOutOfBoundsException e) { > > - // expected > > - } > > - > > - try { > > - bis.read(new byte[0], 1, 1); > > - fail("should throw IndexOutOfBoundsException"); > > - } catch (IndexOutOfBoundsException e) { > > - // expected > > - } > > - > > - bis.close(); > > - > > - try { > > - bis.read(null, -1, -1); > > - fail("should throw IOException"); > > - } catch (IOException e) { > > - // expected > > - } > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#read(byte[], int, int) > > - */ > > - public void test_read$BII() throws IOException { > > - byte[] buf1 = new byte[100]; > > - is.skip(3000); > > - is.mark(1000); > > - is.read(buf1, 0, buf1.length); > > - assertTrue("Failed to read correct data", new String(buf1, 0, > > - buf1.length).equals(fileString.substring(3000, 3100))); > > - > > - BufferedInputStream bufin = new BufferedInputStream(new > InputStream() { > > - int size = 2, pos = 0; > > - > > - byte[] contents = new byte[size]; > > - > > - @Override > > - public int read() throws IOException { > > - if (pos >= size) { > > - throw new IOException("Read past end of data"); > > - } > > - return contents[pos++]; > > - } > > - > > - @Override > > - public int read(byte[] buf, int off, int len) throws > IOException { > > - if (pos >= size) { > > - throw new IOException("Read past end of data"); > > - } > > - int toRead = len; > > - if (toRead > available()) { > > - toRead = available(); > > - } > > - System.arraycopy(contents, pos, buf, off, toRead); > > - pos += toRead; > > - return toRead; > > - } > > - > > - @Override > > - public int available() { > > - return size - pos; > > - } > > - }); > > - bufin.read(); > > - int result = bufin.read(new byte[2], 0, 2); > > - assertTrue("Incorrect result: " + result, result == 1); > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#reset() > > - */ > > - public void test_reset() throws IOException { > > - byte[] buf1 = new byte[10]; > > - byte[] buf2 = new byte[10]; > > - is.mark(2000); > > - is.read(buf1, 0, 10); > > - is.reset(); > > - is.read(buf2, 0, 10); > > - is.reset(); > > - assertTrue("Reset failed", new String(buf1, 0, buf1.length) > > - .equals(new String(buf2, 0, buf2.length))); > > - > > - BufferedInputStream bIn = new BufferedInputStream( > > - new ByteArrayInputStream("1234567890".getBytes())); > > - bIn.mark(10); > > - for (int i = 0; i < 11; i++) { > > - bIn.read(); > > - } > > - bIn.reset(); > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#reset() > > - */ > > - public void test_reset_Exception() throws IOException { > > - BufferedInputStream bis = new BufferedInputStream(null); > > - > > - // throws IOException with message "Mark has been invalidated" > > - try { > > - bis.reset(); > > - fail("should throw IOException"); > > - } catch (IOException e) { > > - // expected > > - } > > - > > - // does not throw IOException > > - bis.mark(1); > > - bis.reset(); > > - > > - bis.close(); > > - > > - // throws IOException with message "stream is closed" > > - try { > > - bis.reset(); > > - fail("should throw IOException"); > > - } catch (IOException e) { > > - // expected > > - } > > - } > > - > > - /** > > - * @tests java.io.BufferedInputStream#skip(long) > > - */ > > - public void test_skipJ() throws IOException { > > - byte[] buf1 = new byte[10]; > > - is.mark(2000); > > - is.skip(1000); > > - is.read(buf1, 0, buf1.length); > > - is.reset(); > > - assertTrue("Failed to skip to correct position", new > String(buf1, 0, > > - buf1.length).equals(fileString.substring(1000, 1010))); > > - > > - // regression for HARMONY-667 > > - try { > > - BufferedInputStream buf = new BufferedInputStream(null, 5); > > - buf.skip(10); > > - fail("Should throw IOException"); > > - } catch (IOException e) { > > - // Expected > > - } > > - } > > - > > - /** > > - * Sets up the fixture, for example, open a network connection. This > method > > - * is called before a test is executed. > > - */ > > - @Override > > - protected void setUp() throws IOException { > > - fileName = System.getProperty("user.dir"); > > - String separator = System.getProperty("file.separator"); > > - if (fileName.charAt(fileName.length() - 1) == > separator.charAt(0)) { > > - fileName = Support_PlatformFile.getNewPlatformFile(fileName, > > - "input.tst"); > > - } else { > > - fileName = Support_PlatformFile.getNewPlatformFile(fileName > > - + separator, "input.tst"); > > - } > > - OutputStream fos = new FileOutputStream(fileName); > > - fos.write(fileString.getBytes()); > > - fos.close(); > > - isFile = new FileInputStream(fileName); > > - is = new BufferedInputStream(isFile); > > - } > > - > > - /** > > - * Tears down the fixture, for example, close a network connection. > This > > - * method is called after a test is executed. > > - */ > > - @Override > > - protected void tearDown() { > > - try { > > - is.close(); > > - } catch (Exception e) { > > - } > > - try { > > - File f = new File(fileName); > > - f.delete(); > > - } catch (Exception e) { > > - } > > - } > > -} > > +/* > > + * 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.harmony.luni.tests.java.io; > > + > > +import java.io.BufferedInputStream; > > +import java.io.ByteArrayInputStream; > > +import java.io.File; > > +import java.io.FileInputStream; > > +import java.io.FileOutputStream; > > +import java.io.IOException; > > +import java.io.InputStream; > > +import java.io.OutputStream; > > +import junit.framework.TestCase; > > +import tests.support.Support_PlatformFile; > > + > > +public class BufferedInputStreamTest extends TestCase { > > + > > + public String fileName; > > + > > + private BufferedInputStream is; > > + > > + private FileInputStream isFile; > > + > > + byte[] ibuf = new byte[4096]; > > + > > + public String fileString = > "Test_All_Tests\nTest_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang > _Cl > > > > assNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_la > ng_ > > > > Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_S > ock > > > > etException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n"; > > + > > + /* > > + * @tests java.io.BufferedInputStream(InputStream) > > + */ > > + public void test_ConstructorLjava_io_InputStream() { > > + try { > > + BufferedInputStream str = new BufferedInputStream(null); > > + str.read(); > > + fail("Expected an IOException"); > > + } catch (IOException e) { > > + // Expected > > + } > > + } > > + > > + /* > > + * @tests java.io.BufferedInputStream(InputStream) > > + */ > > + public void test_ConstructorLjava_io_InputStreamI() throws > IOException { > > + try { > > + BufferedInputStream str = new BufferedInputStream(null, 1); > > + str.read(); > > + fail("Expected an IOException"); > > + } catch (IOException e) { > > + // Expected > > + } > > + > > + // Test for method > java.io.BufferedInputStream(java.io.InputStream, int) > > + > > + // Create buffer with exact size of file > > + is = new BufferedInputStream(isFile, this.fileString.length()); > > + // Ensure buffer gets filled by evaluating one read > > + is.read(); > > + // Close underlying FileInputStream, all but 1 buffered bytes > should > > + // still be available. > > + isFile.close(); > > + // Read the remaining buffered characters, no IOException should > > + // occur. > > + is.skip(this.fileString.length() - 2); > > + is.read(); > > + try { > > + // is.read should now throw an exception because it will > have to > > + // be filled. > > + is.read(); > > + fail("Exception should have been triggered by read()"); > > + } catch (IOException e) { > > + // Expected > > + } > > + > > + // regression test for harmony-2407 > > + new MockBufferedInputStream(null); > > + assertNotNull(MockBufferedInputStream.buf); > > + MockBufferedInputStream.buf = null; > > + new MockBufferedInputStream(null, 100); > > + assertNotNull(MockBufferedInputStream.buf); > > + } > > + > > + static class MockBufferedInputStream extends BufferedInputStream { > > + static byte[] buf; > > + > > + MockBufferedInputStream(InputStream is) throws IOException { > > + super(is); > > + buf = super.buf; > > + } > > + > > + MockBufferedInputStream(InputStream is, int size) throws > IOException { > > + super(is, size); > > + buf = super.buf; > > + } > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#available() > > + */ > > + public void test_available() throws IOException { > > + assertTrue("Returned incorrect number of available bytes", is > > + .available() == fileString.length()); > > + > > + // Test that a closed stream throws an IOE for available() > > + BufferedInputStream bis = new BufferedInputStream( > > + new ByteArrayInputStream(new byte[] { 'h', 'e', 'l', > 'l', 'o', > > + ' ', 't', 'i', 'm' })); > > + int available = bis.available(); > > + bis.close(); > > + assertTrue(available != 0); > > + > > + try { > > + bis.available(); > > + fail("Expected test to throw IOE."); > > + } catch (IOException ex) { > > + // expected > > + } > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#close() > > + */ > > + public void test_close() throws IOException { > > + new BufferedInputStream(isFile).close(); > > + > > + // regression for HARMONY-667 > > + BufferedInputStream buf = new BufferedInputStream(null, 5); > > + buf.close(); > > + > > + InputStream in = new InputStream() { > > + Object lock = new Object(); > > + > > + @Override > > + public int read() { > > + return 1; > > + } > > + > > + @Override > > + public int read(byte[] buf, int offset, int length) { > > + synchronized (lock) { > > + try { > > + lock.wait(3000); > > + } catch (InterruptedException e) { > > + // Ignore > > + } > > + } > > + return 1; > > + } > > + > > + @Override > > + public void close() { > > + synchronized (lock) { > > + lock.notifyAll(); > > + } > > + } > > + }; > > + final BufferedInputStream bufin = new BufferedInputStream(in); > > + Thread thread = new Thread(new Runnable() { > > + public void run() { > > + try { > > + Thread.sleep(1000); > > + bufin.close(); > > + } catch (Exception e) { > > + // Ignored > > + } > > + } > > + }); > > + thread.start(); > > + try { > > + bufin.read(new byte[100], 0, 99); > > + fail("Should throw IOException"); > > + } catch (IOException e) { > > + // Expected > > + } > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#mark(int) > > + */ > > + public void test_markI() throws IOException { > > + byte[] buf1 = new byte[100]; > > + byte[] buf2 = new byte[100]; > > + is.skip(3000); > > + is.mark(1000); > > + is.read(buf1, 0, buf1.length); > > + is.reset(); > > + is.read(buf2, 0, buf2.length); > > + is.reset(); > > + assertTrue("Failed to mark correct position", new String(buf1, > 0, > > + buf1.length).equals(new String(buf2, 0, buf2.length))); > > + > > + byte[] bytes = new byte[256]; > > + for (int i = 0; i < 256; i++) { > > + bytes[i] = (byte) i; > > + } > > + InputStream in = new BufferedInputStream( > > + new ByteArrayInputStream(bytes), 12); > > + in.skip(6); > > + in.mark(14); > > + in.read(new byte[14], 0, 14); > > + in.reset(); > > + assertTrue("Wrong bytes", in.read() == 6 && in.read() == 7); > > + > > + in = new BufferedInputStream(new ByteArrayInputStream(bytes), > 12); > > + in.skip(6); > > + in.mark(8); > > + in.skip(7); > > + in.reset(); > > + assertTrue("Wrong bytes 2", in.read() == 6 && in.read() == 7); > > + > > + BufferedInputStream buf = new BufferedInputStream( > > + new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4 }), > 2); > > + buf.mark(3); > > + bytes = new byte[3]; > > + int result = buf.read(bytes); > > + assertEquals(3, result); > > + assertEquals("Assert 0:", 0, bytes[0]); > > + assertEquals("Assert 1:", 1, bytes[1]); > > + assertEquals("Assert 2:", 2, bytes[2]); > > + assertEquals("Assert 3:", 3, buf.read()); > > + > > + buf = new BufferedInputStream(new ByteArrayInputStream(new > byte[] { 0, > > + 1, 2, 3, 4 }), 2); > > + buf.mark(3); > > + bytes = new byte[4]; > > + result = buf.read(bytes); > > + assertEquals(4, result); > > + assertEquals("Assert 4:", 0, bytes[0]); > > + assertEquals("Assert 5:", 1, bytes[1]); > > + assertEquals("Assert 6:", 2, bytes[2]); > > + assertEquals("Assert 7:", 3, bytes[3]); > > + assertEquals("Assert 8:", 4, buf.read()); > > + assertEquals("Assert 9:", -1, buf.read()); > > + > > + buf = new BufferedInputStream(new ByteArrayInputStream(new > byte[] { 0, > > + 1, 2, 3, 4 }), 2); > > + buf.mark(Integer.MAX_VALUE); > > + buf.read(); > > + buf.close(); > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#markSupported() > > + */ > > + public void test_markSupported() { > > + assertTrue("markSupported returned incorrect value", > is.markSupported()); > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#read() > > + */ > > + public void test_read() throws IOException { > > + int c = is.read(); > > + assertTrue("read returned incorrect char", c == > fileString.charAt(0)); > > + > > + byte[] bytes = new byte[256]; > > + for (int i = 0; i < 256; i++) { > > + bytes[i] = (byte) i; > > + } > > + InputStream in = new BufferedInputStream( > > + new ByteArrayInputStream(bytes), 12); > > + assertEquals("Wrong initial byte", 0, in.read()); // Fill the > > + // buffer > > + byte[] buf = new byte[14]; > > + in.read(buf, 0, 14); // Read greater than the buffer > > + assertTrue("Wrong block read data", new String(buf, 0, 14) > > + .equals(new String(bytes, 1, 14))); > > + assertEquals("Wrong bytes", 15, in.read()); // Check next byte > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#read(byte[], int, int) > > + */ > > + public void test_read$BII_Exception() throws IOException { > > + BufferedInputStream bis = new BufferedInputStream(null); > > + try { > > + bis.read(null, -1, -1); > > + fail("should throw NullPointerException"); > > + } catch (NullPointerException e) { > > + // expected > > + } > > + > > + try { > > + bis.read(new byte[0], -1, -1); > > + fail("should throw IndexOutOfBoundsException"); > > + } catch (IndexOutOfBoundsException e) { > > + // expected > > + } > > + > > + try { > > + bis.read(new byte[0], 1, -1); > > + fail("should throw IndexOutOfBoundsException"); > > + } catch (IndexOutOfBoundsException e) { > > + // expected > > + } > > + > > + try { > > + bis.read(new byte[0], 1, 1); > > + fail("should throw IndexOutOfBoundsException"); > > + } catch (IndexOutOfBoundsException e) { > > + // expected > > + } > > + > > + bis.close(); > > + > > + try { > > + bis.read(null, -1, -1); > > + fail("should throw IOException"); > > + } catch (IOException e) { > > + // expected > > + } > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#read(byte[], int, int) > > + */ > > + public void test_read$BII() throws IOException { > > + byte[] buf1 = new byte[100]; > > + is.skip(3000); > > + is.mark(1000); > > + is.read(buf1, 0, buf1.length); > > + assertTrue("Failed to read correct data", new String(buf1, 0, > > + buf1.length).equals(fileString.substring(3000, 3100))); > > + > > + BufferedInputStream bufin = new BufferedInputStream(new > InputStream() { > > + int size = 2, pos = 0; > > + > > + byte[] contents = new byte[size]; > > + > > + @Override > > + public int read() throws IOException { > > + if (pos >= size) { > > + throw new IOException("Read past end of data"); > > + } > > + return contents[pos++]; > > + } > > + > > + @Override > > + public int read(byte[] buf, int off, int len) throws > IOException { > > + if (pos >= size) { > > + throw new IOException("Read past end of data"); > > + } > > + int toRead = len; > > + if (toRead > available()) { > > + toRead = available(); > > + } > > + System.arraycopy(contents, pos, buf, off, toRead); > > + pos += toRead; > > + return toRead; > > + } > > + > > + @Override > > + public int available() { > > + return size - pos; > > + } > > + }); > > + bufin.read(); > > + int result = bufin.read(new byte[2], 0, 2); > > + assertTrue("Incorrect result: " + result, result == 1); > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#reset() > > + */ > > + public void test_reset() throws IOException { > > + byte[] buf1 = new byte[10]; > > + byte[] buf2 = new byte[10]; > > + is.mark(2000); > > + is.read(buf1, 0, 10); > > + is.reset(); > > + is.read(buf2, 0, 10); > > + is.reset(); > > + assertTrue("Reset failed", new String(buf1, 0, buf1.length) > > + .equals(new String(buf2, 0, buf2.length))); > > + > > + BufferedInputStream bIn = new BufferedInputStream( > > + new ByteArrayInputStream("1234567890".getBytes())); > > + bIn.mark(10); > > + for (int i = 0; i < 11; i++) { > > + bIn.read(); > > + } > > + bIn.reset(); > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#reset() > > + */ > > + public void test_reset_Exception() throws IOException { > > + BufferedInputStream bis = new BufferedInputStream(null); > > + > > + // throws IOException with message "Mark has been invalidated" > > + try { > > + bis.reset(); > > + fail("should throw IOException"); > > + } catch (IOException e) { > > + // expected > > + } > > + > > + // does not throw IOException > > + bis.mark(1); > > + bis.reset(); > > + > > + bis.close(); > > + > > + // throws IOException with message "stream is closed" > > + try { > > + bis.reset(); > > + fail("should throw IOException"); > > + } catch (IOException e) { > > + // expected > > + } > > + } > > + > > + /** > > + * @tests java.io.BufferedInputStream#skip(long) > > + */ > > + public void test_skipJ() throws IOException { > > + byte[] buf1 = new byte[10]; > > + is.mark(2000); > > + is.skip(1000); > > + is.read(buf1, 0, buf1.length); > > + is.reset(); > > + assertTrue("Failed to skip to correct position", new > String(buf1, 0, > > + buf1.length).equals(fileString.substring(1000, 1010))); > > + > > + // regression for HARMONY-667 > > + try { > > + BufferedInputStream buf = new BufferedInputStream(null, 5); > > + buf.skip(10); > > + fail("Should throw IOException"); > > + } catch (IOException e) { > > + // Expected > > + } > > + } > > + > > + /** > > + * Sets up the fixture, for example, open a network connection. This > method > > + * is called before a test is executed. > > + */ > > + @Override > > + protected void setUp() throws IOException { > > + fileName = System.getProperty("user.dir"); > > + String separator = System.getProperty("file.separator"); > > + if (fileName.charAt(fileName.length() - 1) == > separator.charAt(0)) { > > + fileName = Support_PlatformFile.getNewPlatformFile(fileName, > > + "input.tst"); > > + } else { > > + fileName = Support_PlatformFile.getNewPlatformFile(fileName > > + + separator, "input.tst"); > > + } > > + OutputStream fos = new FileOutputStream(fileName); > > + fos.write(fileString.getBytes()); > > + fos.close(); > > + isFile = new FileInputStream(fileName); > > + is = new BufferedInputStream(isFile); > > + } > > + > > + /** > > + * Tears down the fixture, for example, close a network connection. > This > > + * method is called after a test is executed. > > + */ > > + @Override > > + protected void tearDown() { > > + try { > > + is.close(); > > + } catch (Exception e) { > > + } > > + try { > > + File f = new File(fileName); > > + f.delete(); > > + } catch (Exception e) { > > + } > > + } > > +} > > > > > > > -- Best Regards Sean, Xiao Xia Qiu China Software Development Lab, IBM
