예제 #1
0
        /// <summary>
        /// Read characters into a portion of an array, reading from the underlying
        /// stream at most once if necessary.
        /// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private int read1(byte[] b, int off, int len) throws IOException
        private int Read1(sbyte[] b, int off, int len)
        {
            int avail = Count - Pos;

            if (avail <= 0)
            {
                /* If the requested length is at least as large as the buffer, and
                 * if there is no mark/reset activity, do not bother to copy the
                 * bytes into the local buffer.  In this way buffered streams will
                 * cascade harmlessly. */
                if (len >= BufIfOpen.Length && Markpos < 0)
                {
                    return(InIfOpen.Read(b, off, len));
                }
                Fill();
                avail = Count - Pos;
                if (avail <= 0)
                {
                    return(-1);
                }
            }
            int cnt = (avail < len) ? avail : len;

            System.Array.Copy(BufIfOpen, Pos, b, off, cnt);
            Pos += cnt;
            return(cnt);
        }
예제 #2
0
        /// <summary>
        /// Fills the buffer with more data, taking into account
        /// shuffling and other tricks for dealing with marks.
        /// Assumes that it is being called by a synchronized method.
        /// This method also assumes that all data has already been read in,
        /// hence pos > count.
        /// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private void fill() throws IOException
        private void Fill()
        {
            sbyte[] buffer = BufIfOpen;
            if (Markpos < 0)
            {
                Pos = 0;                   // no mark: throw away the buffer
            }
            else if (Pos >= buffer.Length) // no room left in buffer
            {
                if (Markpos > 0)           // can throw away early part of the buffer
                {
                    int sz = Pos - Markpos;
                    System.Array.Copy(buffer, Markpos, buffer, 0, sz);
                    Pos     = sz;
                    Markpos = 0;
                }
                else if (buffer.Length >= Marklimit)
                {
                    Markpos = -1;                // buffer got too big, invalidate mark
                    Pos     = 0;                 // drop buffer contents
                }
                else if (buffer.Length >= MAX_BUFFER_SIZE)
                {
                    throw new OutOfMemoryError("Required array size too large");
                }                 // grow buffer
                else
                {
                    int nsz = (Pos <= MAX_BUFFER_SIZE - Pos) ? Pos * 2 : MAX_BUFFER_SIZE;
                    if (nsz > Marklimit)
                    {
                        nsz = Marklimit;
                    }
                    sbyte[] nbuf = new sbyte[nsz];
                    System.Array.Copy(buffer, 0, nbuf, 0, Pos);
                    if (!BufUpdater.CompareAndSet(this, buffer, nbuf))
                    {
                        // Can't replace buf if there was an async close.
                        // Note: This would need to be changed if fill()
                        // is ever made accessible to multiple threads.
                        // But for now, the only way CAS can fail is via close.
                        // assert buf == null;
                        throw new IOException("Stream closed");
                    }
                    buffer = nbuf;
                }
            }
            Count = Pos;
            int n = InIfOpen.Read(buffer, Pos, buffer.Length - Pos);

            if (n > 0)
            {
                Count = n + Pos;
            }
        }