private boolean checkFill()

in geronimo-mail_2.1_spec/src/main/java/jakarta/mail/util/SharedFileInputStream.java [186:272]


    private boolean checkFill() throws IOException {
        // if we have data in the buffer currently, just return
        if (pos < count) {
            return true;
        }

        // ugh, extending BufferedInputStream also means supporting mark positions.  That complicates everything.
        // life is so much easier if marks are not used....
        if (markpos < 0) {
            // reset back to the buffer position
            pos = 0;
            // this will be the new position within the file once we're read some data.
            bufpos += count;
        }
        else {
            // we have marks to worry about....damn.
            // if we have room in the buffer to read more data, then we will.  Otherwise, we need to see
            // if it's possible to shift the data in the buffer or extend the buffer (up to the mark limit).
            if (pos >= buf.length) {
                // the mark position is not at the beginning of the buffer, so just shuffle the bytes, leaving
                // us room to read more data.
                if (markpos > 0) {
                    // this is the size of the data we need to keep.
                    final int validSize = pos - markpos;
                    // perform the shift operation.
                    System.arraycopy(buf, markpos, buf, 0, validSize);
                    // now adjust the positional markers for this shift.
                    pos = validSize;
                    bufpos += markpos;
                    markpos = 0;
                }
                // the mark is at the beginning, and we've used up the buffer.  See if we're allowed to
                // extend this.
                else if (buf.length < marklimit) {
                    // try to double this, but throttle to the mark limit
                    final int newSize = Math.min(buf.length * 2, marklimit);

                    final byte[] newBuffer = new byte[newSize];
                    System.arraycopy(buf, 0, newBuffer, 0, buf.length);

                    // replace the old buffer.  Note that all other positional markers remain the same here.
                    buf = newBuffer;
                }
                // we've got further than allowed, so invalidate the mark, and just reset the buffer
                else {
                    markpos = -1;
                    pos = 0;
                    bufpos += count;
                }
            }
        }

        // if we're past our designated end, force an eof.
        if (bufpos + pos >= start + datalen) {
            // make sure we zero the count out, otherwise we'll reuse this data 
            // if called again. 
            count = pos; 
            return false;
        }

        // seek to the read location start.  Note this is a shared file, so this assumes all of the methods
        // doing buffer fills will be synchronized.
        int fillLength = buf.length - pos;

        // we might be working with a subset of the file data, so normal eof processing might not apply.
        // we need to limit how much we read to the data length.
        if (bufpos - start + pos + fillLength > datalen) {
            fillLength = (int)(datalen - (bufpos - start + pos));
        }

        // finally, try to read more data into the buffer.
        fillLength = source.read(bufpos + pos, buf, pos, fillLength);

        // we weren't able to read anything, count this as an eof failure.
        if (fillLength <= 0) {
            // make sure we zero the count out, otherwise we'll reuse this data 
            // if called again. 
            count = pos; 
            return false;
        }

        // set the new buffer count
        count = fillLength + pos;

        // we have data in the buffer.
        return true;
    }