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

com.github.skjolber.unzip.UrlSeekableByteChannel Maven / Gradle / Ivy

package com.github.skjolber.unzip;

import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SeekableByteChannel;
import java.util.concurrent.atomic.AtomicBoolean;

public class UrlSeekableByteChannel implements SeekableByteChannel {

    private final AtomicBoolean closed = new AtomicBoolean();
    private int position;

    private UrlByteChannelCache cache;

	public UrlSeekableByteChannel(URL url, int chunkLength) {
		this(url, chunkLength, -1);
	}

	public UrlSeekableByteChannel(URL url, int chunkLength, int concurrentConnections) {
		this(new UrlByteChannelCache(url, chunkLength, concurrentConnections));
	}
	
    public UrlSeekableByteChannel(UrlByteChannelCache cache) {
		this.cache = cache;
	}

	@Override
    public SeekableByteChannel position(long newPosition) throws IOException {
        ensureOpen();
        if (newPosition < 0L || newPosition > Integer.MAX_VALUE) {
            throw new IllegalArgumentException("Position has to be in range 0.. " + Integer.MAX_VALUE);
        }
        position = (int) newPosition;
        return this;
    }

    @Override
    public long position() {
        return position;
    }
    
    @Override
    public SeekableByteChannel truncate(long newSize) {
    	throw new RuntimeException();
    }
    
    @Override
    public int read(ByteBuffer buf) throws IOException {
        ensureOpen();
        repositionIfNecessary();
        int wanted = buf.remaining();
        int possible = cache.size() - position;
        if (possible <= 0) {
            return -1;
        }
        if (wanted > possible) {
            wanted = possible;
        }
        
        int read = cache.put(buf, position, wanted);
    	
        position += read;
        return read;
    }


	@Override
    public void close() {
        closed.set(true);
    }

    @Override
    public boolean isOpen() {
        return !closed.get();
    }

    @Override
    public int write(ByteBuffer b) throws IOException {
    	throw new RuntimeException();
    }

    private void ensureOpen() throws ClosedChannelException {
        if (!isOpen()) {
            throw new ClosedChannelException();
        }
    }    
    
    private void repositionIfNecessary() throws IOException {
        if (position > cache.size()) {
            position = cache.size();
        }
    }

	@Override
	public long size() throws IOException {
		return cache.size();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy