harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sean Qiu" <sean.xx....@gmail.com>
Subject Re: [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/BufferedInputStrea
Date Thu, 04 Dec 2008 05:11:31 GMT
I'll revert it back and reopen the JIRA. Seem it needs more investigation
for this issue.What do you think about it?

2008/12/2 Tim Ellison <t.p.ellison@gmail.com>

> 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 <t.p.ellison@gmail.com>
> >
> >> 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 @@
> >>>
> >>>  /**
> >>>   * <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_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) {
> >>> +        }
> >>> +    }
> >>> +}
> >>>
> >>>
> >>>
> >
> >
> >
>



-- 
Best Regards
Sean, Xiao Xia Qiu

China Software Development Lab, IBM

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message