private boolean refillBuffer(final boolean mustSucceed) throws IOException
    {
        if (bufferPos < bufferSize)
        {
            throw new IllegalStateException(
                    "refillBuffer() called when buffer wasn't empty.");
        }

        if (totalBytesRetired + bufferSize == currentLimit)
        {
            // Oops, we hit a limit.
            if (mustSucceed)
            {
                throw ProtobufException.truncatedMessage();
            }
            else
            {
                return false;
            }
        }

        totalBytesRetired += bufferSize;

        bufferPos = 0;
        bufferSize = (input == null) ? -1 : input.read(buffer);
        if (bufferSize == 0 || bufferSize < -1)
        {
            throw new IllegalStateException(
                    "InputStream#read(byte[]) returned invalid result: " + bufferSize +
                            "\nThe InputStream implementation is buggy.");
        }
        if (bufferSize == -1)
        {
            bufferSize = 0;
            if (mustSucceed)
            {
                throw ProtobufException.truncatedMessage();
            }
            else
            {
                return false;
            }
        }
        else
        {
            recomputeBufferSizeAfterLimit();
            final int totalBytesRead =
                    totalBytesRetired + bufferSize + bufferSizeAfterLimit;
            if (totalBytesRead > sizeLimit || totalBytesRead < 0)
            {
                throw ProtobufException.sizeLimitExceeded();
            }
            return true;
        }
    }
Called with {@code this.buffer} is empty to read more bytes from the input. If {@code mustSucceed} is true,
refillBuffer() guarantees that either there will be at least one byte in the buffer when it returns or it will
throw an exception. If {@code mustSucceed} is false, refillBuffer() returns false if no more bytes were
available.
protostuff-core/src/main/java/io/protostuff/CodedInput.java