All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.undefinedlabs.scope.deps.okio.RealBufferedSource Maven / Gradle / Ivy

Go to download

Scope is a APM for tests to give engineering teams unprecedented visibility into their CI process to quickly identify, troubleshoot and fix failed builds. This artifact contains dependencies for Scope.

There is a newer version: 0.14.0-beta.2
Show newest version
package com.undefinedlabs.scope.deps.okio;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import static com.undefinedlabs.scope.deps.okio.Util.checkOffsetAndCount;

final class RealBufferedSource implements BufferedSource {
    public final Buffer buffer = new Buffer();
    public final Source source;
    boolean closed;

    RealBufferedSource(Source source) {
        if (source == null) throw new NullPointerException("source == null");
        this.source = source;
    }

    @Override public Buffer buffer() {
        return buffer;
    }

    @Override public long read(Buffer sink, long byteCount) throws IOException {
        if (sink == null) throw new IllegalArgumentException("sink == null");
        if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
        if (closed) throw new IllegalStateException("closed");

        if (buffer.size == 0) {
            long read = source.read(buffer, Segment.SIZE);
            if (read == -1) return -1;
        }

        long toRead = Math.min(byteCount, buffer.size);
        return buffer.read(sink, toRead);
    }

    @Override public boolean exhausted() throws IOException {
        if (closed) throw new IllegalStateException("closed");
        return buffer.exhausted() && source.read(buffer, Segment.SIZE) == -1;
    }

    @Override public void require(long byteCount) throws IOException {
        if (!request(byteCount)) throw new EOFException();
    }

    @Override public boolean request(long byteCount) throws IOException {
        if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
        if (closed) throw new IllegalStateException("closed");
        while (buffer.size < byteCount) {
            if (source.read(buffer, Segment.SIZE) == -1) return false;
        }
        return true;
    }

    @Override public byte readByte() throws IOException {
        require(1);
        return buffer.readByte();
    }

    @Override public ByteString readByteString() throws IOException {
        buffer.writeAll(source);
        return buffer.readByteString();
    }

    @Override public ByteString readByteString(long byteCount) throws IOException {
        require(byteCount);
        return buffer.readByteString(byteCount);
    }

    @Override public int select(Options options) throws IOException {
        if (closed) throw new IllegalStateException("closed");

        while (true) {
            int index = buffer.selectPrefix(options);
            if (index == -1) return -1;

            // If the prefix match actually matched a full byte string, consume it and return it.
            int selectedSize = options.byteStrings[index].size();
            if (selectedSize <= buffer.size) {
                buffer.skip(selectedSize);
                return index;
            }

            // We need to grow the buffer. Do that, then try it all again.
            if (source.read(buffer, Segment.SIZE) == -1) return -1;
        }
    }

    @Override public byte[] readByteArray() throws IOException {
        buffer.writeAll(source);
        return buffer.readByteArray();
    }

    @Override public byte[] readByteArray(long byteCount) throws IOException {
        require(byteCount);
        return buffer.readByteArray(byteCount);
    }

    @Override public int read(byte[] sink) throws IOException {
        return read(sink, 0, sink.length);
    }

    @Override public void readFully(byte[] sink) throws IOException {
        try {
            require(sink.length);
        } catch (EOFException e) {
            // The underlying source is exhausted. Copy the bytes we got before rethrowing.
            int offset = 0;
            while (buffer.size > 0) {
                int read = buffer.read(sink, offset, (int) buffer.size);
                if (read == -1) throw new AssertionError();
                offset += read;
            }
            throw e;
        }
        buffer.readFully(sink);
    }

    @Override public int read(byte[] sink, int offset, int byteCount) throws IOException {
        checkOffsetAndCount(sink.length, offset, byteCount);

        if (buffer.size == 0) {
            long read = source.read(buffer, Segment.SIZE);
            if (read == -1) return -1;
        }

        int toRead = (int) Math.min(byteCount, buffer.size);
        return buffer.read(sink, offset, toRead);
    }

    @Override public void readFully(Buffer sink, long byteCount) throws IOException {
        try {
            require(byteCount);
        } catch (EOFException e) {
            // The underlying source is exhausted. Copy the bytes we got before rethrowing.
            sink.writeAll(buffer);
            throw e;
        }
        buffer.readFully(sink, byteCount);
    }

    @Override public long readAll(Sink sink) throws IOException {
        if (sink == null) throw new IllegalArgumentException("sink == null");

        long totalBytesWritten = 0;
        while (source.read(buffer, Segment.SIZE) != -1) {
            long emitByteCount = buffer.completeSegmentByteCount();
            if (emitByteCount > 0) {
                totalBytesWritten += emitByteCount;
                sink.write(buffer, emitByteCount);
            }
        }
        if (buffer.size() > 0) {
            totalBytesWritten += buffer.size();
            sink.write(buffer, buffer.size());
        }
        return totalBytesWritten;
    }

    @Override public String readUtf8() throws IOException {
        buffer.writeAll(source);
        return buffer.readUtf8();
    }

    @Override public String readUtf8(long byteCount) throws IOException {
        require(byteCount);
        return buffer.readUtf8(byteCount);
    }

    @Override public String readString(Charset charset) throws IOException {
        if (charset == null) throw new IllegalArgumentException("charset == null");

        buffer.writeAll(source);
        return buffer.readString(charset);
    }

    @Override public String readString(long byteCount, Charset charset) throws IOException {
        require(byteCount);
        if (charset == null) throw new IllegalArgumentException("charset == null");
        return buffer.readString(byteCount, charset);
    }

    @Override public String readUtf8Line() throws IOException {
        long newline = indexOf((byte) '\n');

        if (newline == -1) {
            return buffer.size != 0 ? readUtf8(buffer.size) : null;
        }

        return buffer.readUtf8Line(newline);
    }

    @Override public String readUtf8LineStrict() throws IOException {
        return readUtf8LineStrict(Long.MAX_VALUE);
    }

    @Override public String readUtf8LineStrict(long limit) throws IOException {
        if (limit < 0) throw new IllegalArgumentException("limit < 0: " + limit);
        long scanLength = limit == Long.MAX_VALUE ? Long.MAX_VALUE : limit + 1;
        long newline = indexOf((byte) '\n', 0, scanLength);
        if (newline != -1) return buffer.readUtf8Line(newline);
        if (scanLength < Long.MAX_VALUE
                && request(scanLength) && buffer.getByte(scanLength - 1) == '\r'
                && request(scanLength + 1) && buffer.getByte(scanLength) == '\n') {
            return buffer.readUtf8Line(scanLength); // The line was 'limit' UTF-8 bytes followed by \r\n.
        }
        Buffer data = new Buffer();
        buffer.copyTo(data, 0, Math.min(32, buffer.size()));
        throw new EOFException("\\n not found: limit=" + Math.min(buffer.size(), limit)
                + " content=" + data.readByteString().hex() + '…');
    }

    @Override public int readUtf8CodePoint() throws IOException {
        require(1);

        byte b0 = buffer.getByte(0);
        if ((b0 & 0xe0) == 0xc0) {
            require(2);
        } else if ((b0 & 0xf0) == 0xe0) {
            require(3);
        } else if ((b0 & 0xf8) == 0xf0) {
            require(4);
        }

        return buffer.readUtf8CodePoint();
    }

    @Override public short readShort() throws IOException {
        require(2);
        return buffer.readShort();
    }

    @Override public short readShortLe() throws IOException {
        require(2);
        return buffer.readShortLe();
    }

    @Override public int readInt() throws IOException {
        require(4);
        return buffer.readInt();
    }

    @Override public int readIntLe() throws IOException {
        require(4);
        return buffer.readIntLe();
    }

    @Override public long readLong() throws IOException {
        require(8);
        return buffer.readLong();
    }

    @Override public long readLongLe() throws IOException {
        require(8);
        return buffer.readLongLe();
    }

    @Override public long readDecimalLong() throws IOException {
        require(1);

        for (int pos = 0; request(pos + 1); pos++) {
            byte b = buffer.getByte(pos);
            if ((b < '0' || b > '9') && (pos != 0 || b != '-')) {
                // Non-digit, or non-leading negative sign.
                if (pos == 0) {
                    throw new NumberFormatException(String.format(
                            "Expected leading [0-9] or '-' character but was %#x", b));
                }
                break;
            }
        }

        return buffer.readDecimalLong();
    }

    @Override public long readHexadecimalUnsignedLong() throws IOException {
        require(1);

        for (int pos = 0; request(pos + 1); pos++) {
            byte b = buffer.getByte(pos);
            if ((b < '0' || b > '9') && (b < 'a' || b > 'f') && (b < 'A' || b > 'F')) {
                // Non-digit, or non-leading negative sign.
                if (pos == 0) {
                    throw new NumberFormatException(String.format(
                            "Expected leading [0-9a-fA-F] character but was %#x", b));
                }
                break;
            }
        }

        return buffer.readHexadecimalUnsignedLong();
    }

    @Override public void skip(long byteCount) throws IOException {
        if (closed) throw new IllegalStateException("closed");
        while (byteCount > 0) {
            if (buffer.size == 0 && source.read(buffer, Segment.SIZE) == -1) {
                throw new EOFException();
            }
            long toSkip = Math.min(byteCount, buffer.size());
            buffer.skip(toSkip);
            byteCount -= toSkip;
        }
    }

    @Override public long indexOf(byte b) throws IOException {
        return indexOf(b, 0, Long.MAX_VALUE);
    }

    @Override public long indexOf(byte b, long fromIndex) throws IOException {
        return indexOf(b, fromIndex, Long.MAX_VALUE);
    }

    @Override public long indexOf(byte b, long fromIndex, long toIndex) throws IOException {
        if (closed) throw new IllegalStateException("closed");
        if (fromIndex < 0 || toIndex < fromIndex) {
            throw new IllegalArgumentException(
                    String.format("fromIndex=%s toIndex=%s", fromIndex, toIndex));
        }

        while (fromIndex < toIndex) {
            long result = buffer.indexOf(b, fromIndex, toIndex);
            if (result != -1L) return result;

            // The byte wasn't in the buffer. Give up if we've already reached our target size or if the
            // underlying stream is exhausted.
            long lastBufferSize = buffer.size;
            if (lastBufferSize >= toIndex || source.read(buffer, Segment.SIZE) == -1) return -1L;

            // Continue the search from where we left off.
            fromIndex = Math.max(fromIndex, lastBufferSize);
        }
        return -1L;
    }

    @Override public long indexOf(ByteString bytes) throws IOException {
        return indexOf(bytes, 0);
    }

    @Override public long indexOf(ByteString bytes, long fromIndex) throws IOException {
        if (closed) throw new IllegalStateException("closed");

        while (true) {
            long result = buffer.indexOf(bytes, fromIndex);
            if (result != -1) return result;

            long lastBufferSize = buffer.size;
            if (source.read(buffer, Segment.SIZE) == -1) return -1L;

            // Keep searching, picking up from where we left off.
            fromIndex = Math.max(fromIndex, lastBufferSize - bytes.size() + 1);
        }
    }

    @Override public long indexOfElement(ByteString targetBytes) throws IOException {
        return indexOfElement(targetBytes, 0);
    }

    @Override public long indexOfElement(ByteString targetBytes, long fromIndex) throws IOException {
        if (closed) throw new IllegalStateException("closed");

        while (true) {
            long result = buffer.indexOfElement(targetBytes, fromIndex);
            if (result != -1) return result;

            long lastBufferSize = buffer.size;
            if (source.read(buffer, Segment.SIZE) == -1) return -1L;

            // Keep searching, picking up from where we left off.
            fromIndex = Math.max(fromIndex, lastBufferSize);
        }
    }

    @Override public boolean rangeEquals(long offset, ByteString bytes) throws IOException {
        return rangeEquals(offset, bytes, 0, bytes.size());
    }

    @Override
    public boolean rangeEquals(long offset, ByteString bytes, int bytesOffset, int byteCount)
            throws IOException {
        if (closed) throw new IllegalStateException("closed");

        if (offset < 0
                || bytesOffset < 0
                || byteCount < 0
                || bytes.size() - bytesOffset < byteCount) {
            return false;
        }
        for (int i = 0; i < byteCount; i++) {
            long bufferOffset = offset + i;
            if (!request(bufferOffset + 1)) return false;
            if (buffer.getByte(bufferOffset) != bytes.getByte(bytesOffset + i)) return false;
        }
        return true;
    }

    @Override public InputStream inputStream() {
        return new InputStream() {
            @Override public int read() throws IOException {
                if (closed) throw new IOException("closed");
                if (buffer.size == 0) {
                    long count = source.read(buffer, Segment.SIZE);
                    if (count == -1) return -1;
                }
                return buffer.readByte() & 0xff;
            }

            @Override public int read(byte[] data, int offset, int byteCount) throws IOException {
                if (closed) throw new IOException("closed");
                checkOffsetAndCount(data.length, offset, byteCount);

                if (buffer.size == 0) {
                    long count = source.read(buffer, Segment.SIZE);
                    if (count == -1) return -1;
                }

                return buffer.read(data, offset, byteCount);
            }

            @Override public int available() throws IOException {
                if (closed) throw new IOException("closed");
                return (int) Math.min(buffer.size, Integer.MAX_VALUE);
            }

            @Override public void close() throws IOException {
                RealBufferedSource.this.close();
            }

            @Override public String toString() {
                return RealBufferedSource.this + ".inputStream()";
            }
        };
    }

    @Override public void close() throws IOException {
        if (closed) return;
        closed = true;
        source.close();
        buffer.clear();
    }

    @Override public Timeout timeout() {
        return source.timeout();
    }

    @Override public String toString() {
        return "buffer(" + source + ")";
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy