<commit_before>package javafixes.io;

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

import static java.lang.Math.min;

// todo: add into readme
// todo: javadoc
public class LinkedArrayOutputStream extends OutputStream {

    private transient final Object lock = new Object();

    private transient final Node first;
    private transient Node last;

    private transient boolean closed = false;

    public LinkedArrayOutputStream(int arraySize) {
        this.first = new Node(arraySize);
        this.last = this.first;
    }

    public LinkedArrayOutputStream() {
        this(4 * 1024);
    }

    @Override
    public void write(int b) throws IOException {
        last.add((byte) b);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        last.add(b, off, len);
    }

    @Override
    public void close() throws IOException {
        synchronized (lock) {
            closed = true;
        }
    }

    public void copyTo(OutputStream os) throws IOException {
        synchronized (lock) {
            if (!closed) {
                throw new IllegalStateException("Unable to copy content to OutputStream. LinkedArrayOutputStream is not closed yet");
            }

            Node node = first;
            do {
                if (node.writeToIndex != 0) {
                    os.write(node.bytes, 0, node.writeToIndex);
                }
                node = node.next;
            } while(node != null);
        }
    }

    public InputStream toInputStream() {
        synchronized (lock) {
            if (!closed) {
                throw new IllegalStateException("Unable to provide InputStream. LinkedArrayOutputStream is not closed yet");
            }

            return new InputStream() {
                int readIndex = 0;
                Node node = first;

                @Override
                public int read() throws IOException {
                    if (readIndex == node.writeToIndex) {
                        return -1;
                    }

                    int value = node.bytes[readIndex];
                    readIndex++;
                    if (readIndex == node.bytes.length && node.next != null) {
                        node = node.next;
                        readIndex = 0;
                    }
                    return value;
                }
            };
        }<commit_msg>mtymes: improving InputStream generated by LinkedArrayOutputStream<commit_after>package javafixes.io;

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

import static java.lang.Math.min;

// todo: add into readme
// todo: javadoc
public class LinkedArrayOutputStream extends OutputStream {

    private transient final Object lock = new Object();

    private transient final Node first;
    private transient Node last;

    private transient boolean closed = false;

    public LinkedArrayOutputStream(int arraySize) {
        this.first = new Node(arraySize);
        this.last = this.first;
    }

    public LinkedArrayOutputStream() {
        this(4 * 1024);
    }

    @Override
    public void write(int b) throws IOException {
        last.add((byte) b);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        last.add(b, off, len);
    }

    @Override
    public void close() throws IOException {
        synchronized (lock) {
            closed = true;
        }
    }

    public void copyTo(OutputStream os) throws IOException {
        synchronized (lock) {
            if (!closed) {
                throw new IllegalStateException("Unable to copy content to OutputStream. LinkedArrayOutputStream is not closed yet");
            }

            Node node = first;
            do {
                if (node.writeToIndex != 0) {
                    os.write(node.bytes, 0, node.writeToIndex);
                }
                node = node.next;
            } while (node != null);
        }
    }

    public InputStream toInputStream() {
        synchronized (lock) {
            if (!closed) {
                throw new IllegalStateException("Unable to provide InputStream. LinkedArrayOutputStream is not closed yet");
            }

            return new InputStream() {
                int readIndex = 0;
                Node node = first;

                @Override
                public int read() throws IOException {
                    if (readIndex == node.writeToIndex) {
                        return -1;
                    }

                    int value = node.bytes[readIndex];
                    readIndex++;
                    if (readIndex == node.bytes.length && node.next != null) {
                        node = node.next;
                        readIndex = 0;
                    }
                    return value;
                }

                @Override
                public int read(byte[] b, int off, int len) throws IOException {
                    int actualLen = 0;
                    while (len > 0) {
                        int copyNBytes = min(node.writeToIndex - readIndex, len);
                        if (copyNBytes > 0) {
                            System.arraycopy(node.bytes, readIndex, b, off, copyNBytes);

                            actualLen = actualLen + copyNBytes;
                            off = off + copyNBytes;
                            len = len - copyNBytes;
                            readIndex = readIndex + copyNBytes;
                        }
                        if (node.next == null) {
                            break;
                        }

                        if (readIndex == node.bytes.length && node.next != null) {
                            node = node.next;
                            readIndex = 0;
                        }
                    }
                    return (actualLen == 0) ? -1 : actualLen;
                }
            };
        }
{'fraction_non_alphanumeric': 0.0825258937520882, 'fraction_numerical': 0.004343468092215168, 'mean_word_length': 1.3377586880124952, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '6033541', 'n_tokens_mistral': 1488, 'n_tokens_neox': 1380, 'n_words': 422}