public int read(byte[] buffer, long offset, int length) throws ProxyCacheException {
        ProxyCacheUtils.assertBuffer(buffer, offset, length);

        while (!cache.isCompleted() && cache.available() < (offset + length) && !stopped) {
            readSourceAsync();
            waitForSourceData();
            checkReadSourceErrorsCount();
        }
        int read = cache.read(buffer, offset, length);
        if (cache.isCompleted() && percentsAvailable != 100) {
            percentsAvailable = 100;
            onCachePercentsAvailableChanged(100);
        }
        return read;
    }
Proxy for {@link Source} with caching support ({@link Cache}).
<p/>
Can be used only for sources with persistent data (that doesn't change with time).
Method {@link #read(byte[], long, int)} will be blocked while fetching data from source.
Useful for streaming something with caching e.g. streaming video/audio etc.
VideoCache/src/main/java/com/yc/videocache/ProxyCache.java