Return-Path: Delivered-To: apmail-harmony-dev-archive@www.apache.org Received: (qmail 97707 invoked from network); 2 Dec 2008 12:20:48 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 2 Dec 2008 12:20:48 -0000 Received: (qmail 28815 invoked by uid 500); 2 Dec 2008 12:20:58 -0000 Delivered-To: apmail-harmony-dev-archive@harmony.apache.org Received: (qmail 28780 invoked by uid 500); 2 Dec 2008 12:20:58 -0000 Mailing-List: contact dev-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list dev@harmony.apache.org Received: (qmail 28769 invoked by uid 99); 2 Dec 2008 12:20:58 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 02 Dec 2008 04:20:58 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of t.p.ellison@gmail.com designates 74.125.78.147 as permitted sender) Received: from [74.125.78.147] (HELO ey-out-1920.google.com) (74.125.78.147) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 02 Dec 2008 12:19:25 +0000 Received: by ey-out-1920.google.com with SMTP id 4so1318965eyg.24 for ; Tue, 02 Dec 2008 04:20:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:references:in-reply-to :x-enigmail-version:content-type:content-transfer-encoding; bh=i+OP4QxWLulTlGVFEspPBmFCDHpbFnqyqlvuey2MQhk=; b=j3QHMIBX6TVVJQqyE/8tgRpoGPHnTVAdNNrZiZFGRMNAGJLBMpHzRpkxbvdqpZtGPm wi36R2XFz8nLhVgiZURgYHrakekvfgUATljTu285RZaUJOwjkre4D+5PURpverIQEQ3y UXrC9nb74Slh3ACXqz5Dkh9LjDI0DEIaGvlOo= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:x-enigmail-version:content-type :content-transfer-encoding; b=oFP2wGe+MEKXqnbyq/vnL5k+hiw3oYo+BhniA3flYFqYfWb++Ox8qd/BdYc/si6j7r /jHc0uPDjqV1V8gMhuS4AAR6xiFcXfhUtcjYIoJ/sR4eWr7z7o/NYr0PiKWi0oRfcOQU hD+mIBXm8LElDDJXSwmq5Lzl4wQdy8N/1f7M8= Received: by 10.210.72.14 with SMTP id u14mr10733565eba.73.1228220411282; Tue, 02 Dec 2008 04:20:11 -0800 (PST) Received: from ?9.20.183.162? (blueice4n2.uk.ibm.com [195.212.29.92]) by mx.google.com with ESMTPS id b30sm5338003ika.7.2008.12.02.04.19.57 (version=SSLv3 cipher=RC4-MD5); Tue, 02 Dec 2008 04:20:07 -0800 (PST) Message-ID: <493527E7.10304@gmail.com> Date: Tue, 02 Dec 2008 12:19:51 +0000 From: Tim Ellison User-Agent: Thunderbird 2.0.0.18 (Windows/20081105) MIME-Version: 1.0 To: dev@harmony.apache.org Subject: [classlib][luni] BufferedInputStream changes (was: Re: svn commit: r721075 - in /harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/io/BufferedInputStream.java test/api/common/org/apache/harmony/luni/tests/java/io/BufferedInputStreamTest.java) References: <20081127032438.81E3523888A4@eris.apache.org> <492FE34F.3000102@gmail.com> <94d710af0811302156w7bff9b6fvde4310bf97c9d1f4@mail.gmail.com> In-Reply-To: <94d710af0811302156w7bff9b6fvde4310bf97c9d1f4@mail.gmail.com> X-Enigmail-Version: 0.95.7 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Sean Qiu wrote: > 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. The problem is that that the patch I uploaded is not complete. It was there for discussion about the direction I was taking. To complete it will require a new lock to avoid a race when closing the stream and refilling it on different threads. All these changes /may/ be worse than using a synchronized close. Regards, Tim > 2008/11/28 Tim Ellison > >> 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 >> >> qiuxx@apache.org 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 @@ >>> >>> /** >>> * BufferedInputStream is a class which takes an input >> stream and >>> - * buffers the input. In this way, costly interaction with the >>> - * original input stream can be minimized by reading buffered amounts of >> data >>> + * buffers 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 buf. >>> @@ -55,12 +55,10 @@ >>> */ >>> protected int pos; >>> >>> - private boolean closed = false; >>> - >>> /** >>> * Constructs a new BufferedInputStream on the >> InputStream >>> - * in. The default buffer size (8Kb) is allocated and >> all >>> - * reads can now be filtered through this stream. >>> + * in. 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 >>> - * readLimit indicates how many bytes can be read >> before a >>> - * mark is invalidated. Sending reset() will reposition the Stream >> back to >>> - * the marked position provided readLimit has not been >>> - * surpassed. The underlying buffer may be increased in size to >> allow >>> + * readLimit indicates how many bytes can be read >> before a mark >>> + * is invalidated. Sending reset() will reposition the Stream back >> to the >>> + * marked position provided readLimit has not been >> surpassed. >>> + * The underlying buffer may be increased in size to allow >>> * readlimit 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 length bytes from this >> BufferedInputStream >>> - * and stores them in byte array buffer starting at >> offset >>> - * offset. 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 length bytes from this >> BufferedInputStream and >>> + * stores them in byte array buffer starting at offset >>> + * offset. 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 >>> - * readlimit has been passed or no mark >> has >>> - * been set, throw IOException. This implementation resets the >> target >>> - * stream. >>> + * readlimit has been passed or no mark >> 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_l a >> 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_l a >> 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) { >>> + } >>> + } >>> +} >>> >>> >>> > > >