<commit_before>package chav1961.purelib.streams.byte2byte;

import java.io.IOException;
import java.io.InputStream;

public class SequenceInputStream extends InputStream {
	public SequenceInputStream(final InputStream... sources) {
		
	}
	
	@Override
	public int read() throws IOException {
		// TODO Auto-generated method stub
		return 0;
	}
}<commit_msg>Daily commit<commit_after>package chav1961.purelib.streams.byte2byte;

import java.io.IOException;
import java.io.InputStream;

import chav1961.purelib.basic.Utils;

/**
 * <p>This class is used to make input from lot of concatenated input streams. It starts reading from the same first input stream. When EOF will be detected,
 * it switches to the second input stream etc. It also call {@linkplain #switchNext(int)} method before switching. You can override this method to insert some
 * <i>divizor bytes</i> between input streams.</p>
 * @author <NAME> aka chav1961
 * @since 0.0.6
 */
public class SequenceInputStream extends InputStream {
	private final InputStream[]	content;
	private final boolean		closeAll;
	private volatile int		current = 0;
	private volatile byte[]		tail = new byte[0];
	private volatile int		currentTail = 0;
	
	/**
	 * <p>Constructor of the class.</p>
	 * @param sources source streams to concatenate. Can't me empty list and can't contains nulls inside
	 * @throws IllegalArgumentException
	 */
	public SequenceInputStream(final InputStream... sources) throws IllegalArgumentException {
		this(false, sources);
	}
	
	/**
	 * <p>
	 * @param closeAll
	 * @param sources
	 * @throws IllegalArgumentException
	 */
	public SequenceInputStream(final boolean closeAll, final InputStream... sources) throws IllegalArgumentException {
		if (sources == null || sources.length == 0 || Utils.checkArrayContent4Nulls(sources) >= 0) {
			throw new IllegalArgumentException("Input stream list is null, empty or contains nulls inside");
		}
		else {
			this.closeAll = closeAll;
			this.content = sources.clone();
		}
	}
	
	@Override
	public int read() throws IOException {
		if (currentTail < tail.length) {
			return tail[currentTail++];
		}
		else if (current >= content.length) {
			return -1;
		}
		else {
			final int	result = content[current].read();
			
			if (result == -1) {
				tail = switchNext(current);
				currentTail = 0;
				if (closeAll) {
					content[current].close();
				}
				current++;
				return read();
			}
			else {
				return result;
			}
		}
	}

	/**
	 * <p>Process switching of the streams. Can be used to insert some divizor bytes between streams</p> 
	 * @param current current stream to detect EOF. Exactly ordered to constructor parameters order
	 * @return byte array to insert between streams. Can be zero-length array but not null
	 * @throws IOException on any I/O errors
	 */
	protected byte[] switchNext(final int current) throws IOException {
		return new byte[0];
	}
}
{'fraction_non_alphanumeric': 0.09923664122137404, 'fraction_numerical': 0.011103400416377515, 'mean_word_length': 3.781094527363184, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4825785', 'n_tokens_mistral': 927, 'n_tokens_neox': 803, 'n_words': 292}