Csv.java 12.1 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.cq.commerce.pim.common;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;

public class Csv {
    private static final int IO_BUFFER_SIZE = 4096;
    private char fieldSeparatorRead = 44;
    private char commentLineStart = 35;
    private String fieldSeparatorWrite = ",";
    private String rowSeparatorWrite;
    private char fieldDelimiter = 34;
    private char escapeCharacter = 34;
    private String lineSeparator = System.getProperty("line.separator");
    private String nullString = "";
    private Reader input;
    private char[] inputBuffer;
    private int inputBufferPos;
    private int inputBufferStart = -1;
    private int inputBufferEnd;
    private Writer output;
    private boolean endOfLine;
    private boolean endOfFile;

    public Iterator<String[]> read(InputStream in, String charset) throws IOException {
        if (charset == null) {
            charset = System.getProperty("file.encoding");
        }
        in = new BufferedInputStream(in, 4096);
        this.input = new InputStreamReader(in, charset);
        return this.read();
    }

    public Iterator<String[]> read(Reader reader) throws IOException {
        if (!(reader instanceof BufferedReader)) {
            reader = new BufferedReader(reader);
        }
        this.input = reader;
        return this.read();
    }

    private Iterator<String[]> read() throws IOException {
        this.inputBuffer = new char[8192];
        return new RowIterator();
    }

    public void writeInit(OutputStream out, String charset) throws IOException {
        if (charset == null) {
            charset = System.getProperty("file.encoding");
        }
        out = new BufferedOutputStream(out, 4096);
        this.output = new BufferedWriter(new OutputStreamWriter(out, charset));
    }

    public void writeInit(Writer writer) throws IOException {
        if (!(writer instanceof BufferedWriter)) {
            writer = new BufferedWriter(writer);
        }
        this.output = writer;
    }

    public /* varargs */ void writeRow(String ... values) throws IOException {
        for (int i = 0; i < values.length; ++i) {
            String s;
            if (i > 0 && this.fieldSeparatorWrite != null) {
                this.output.write(this.fieldSeparatorWrite);
            }
            if ((s = values[i]) != null) {
                if (this.escapeCharacter != '\u0000') {
                    if (this.fieldDelimiter != '\u0000') {
                        this.output.write(this.fieldDelimiter);
                    }
                    this.output.write(this.escape(s));
                    if (this.fieldDelimiter == '\u0000') continue;
                    this.output.write(this.fieldDelimiter);
                    continue;
                }
                this.output.write(s);
                continue;
            }
            if (this.nullString == null || this.nullString.length() <= 0) continue;
            this.output.write(this.nullString);
        }
        if (this.rowSeparatorWrite != null) {
            this.output.write(this.rowSeparatorWrite);
        }
        this.output.write(this.lineSeparator);
    }

    private String escape(String data) {
        if (data.indexOf(this.fieldDelimiter) < 0 && (this.escapeCharacter == this.fieldDelimiter || data.indexOf(this.escapeCharacter) < 0)) {
            return data;
        }
        StringBuilder buff = new StringBuilder(data.length());
        for (int i = 0; i < data.length(); ++i) {
            char ch = data.charAt(i);
            if (ch == this.fieldDelimiter || ch == this.escapeCharacter) {
                buff.append(this.escapeCharacter);
            }
            buff.append(ch);
        }
        return buff.toString();
    }

    private void pushBack() {
        --this.inputBufferPos;
    }

    private int readChar() throws IOException {
        if (this.inputBufferPos >= this.inputBufferEnd) {
            return this.readBuffer();
        }
        return this.inputBuffer[this.inputBufferPos++];
    }

    private int readBuffer() throws IOException {
        int keep;
        if (this.endOfFile) {
            return -1;
        }
        if (this.inputBufferStart >= 0) {
            keep = this.inputBufferPos - this.inputBufferStart;
            if (keep > 0) {
                char[] src = this.inputBuffer;
                if (keep + 4096 > src.length) {
                    this.inputBuffer = new char[src.length * 2];
                }
                System.arraycopy(src, this.inputBufferStart, this.inputBuffer, 0, keep);
            }
            this.inputBufferStart = 0;
        } else {
            keep = 0;
        }
        this.inputBufferPos = keep;
        int len = this.input.read(this.inputBuffer, keep, 4096);
        if (len == -1) {
            this.inputBufferEnd = -1024;
            this.endOfFile = true;
            ++this.inputBufferPos;
            return -1;
        }
        this.inputBufferEnd = keep + len;
        return this.inputBuffer[this.inputBufferPos++];
    }

    private String readValue() throws IOException {
        int ch;
        this.endOfLine = false;
        this.inputBufferStart = this.inputBufferPos;
        do {
            if ((ch = this.readChar()) == this.fieldDelimiter) {
                boolean containsEscape;
                int sep;
                block15 : {
                    containsEscape = false;
                    this.inputBufferStart = this.inputBufferPos;
                    do {
                        if ((ch = this.readChar()) == this.fieldDelimiter) {
                            ch = this.readChar();
                            if (ch != this.fieldDelimiter) {
                                sep = 2;
                                break block15;
                            }
                            containsEscape = true;
                            continue;
                        }
                        if (ch == this.escapeCharacter) {
                            ch = this.readChar();
                            if (ch < 0) {
                                sep = 1;
                                break block15;
                            }
                            containsEscape = true;
                            continue;
                        }
                        if (ch < 0) break;
                    } while (true);
                    sep = 1;
                }
                String s = new String(this.inputBuffer, this.inputBufferStart, this.inputBufferPos - this.inputBufferStart - sep);
                if (containsEscape) {
                    s = this.unEscape(s);
                }
                this.inputBufferStart = -1;
                while (ch != this.fieldSeparatorRead) {
                    if (ch == 10 || ch < 0 || ch == 13) {
                        this.endOfLine = true;
                        break;
                    }
                    if (ch != 32 && ch != 9) {
                        this.pushBack();
                        break;
                    }
                    ch = this.readChar();
                }
                return s;
            }
            if (ch == 10 || ch < 0 || ch == 13) {
                this.endOfLine = true;
                return null;
            }
            if (ch != this.fieldSeparatorRead) continue;
            return null;
        } while (ch <= 32);
        if (ch == this.commentLineStart) {
            this.inputBufferStart = -1;
            while ((ch = this.readChar()) != 10 && ch >= 0 && ch != 13) {
            }
            this.endOfLine = true;
            return null;
        }
        while ((ch = this.readChar()) != this.fieldSeparatorRead) {
            if (ch != 10 && ch >= 0 && ch != 13) continue;
            this.endOfLine = true;
            break;
        }
        String s = new String(this.inputBuffer, this.inputBufferStart, this.inputBufferPos - this.inputBufferStart - 1);
        this.inputBufferStart = -1;
        return this.readNull(s.trim());
    }

    private String readNull(String s) {
        return s.equals(this.nullString) ? null : s;
    }

    private String unEscape(String s) {
        int idx;
        StringBuilder buff = new StringBuilder(s.length());
        int start = 0;
        char[] chars = null;
        while ((idx = s.indexOf(this.escapeCharacter, start)) >= 0 || (idx = s.indexOf(this.fieldDelimiter, start)) >= 0) {
            if (chars == null) {
                chars = s.toCharArray();
            }
            buff.append(chars, start, idx - start);
            if (idx == s.length() - 1) {
                start = s.length();
                break;
            }
            buff.append(chars[idx + 1]);
            start = idx + 2;
        }
        buff.append(s.substring(start));
        return buff.toString();
    }

    /*
     * Unable to fully structure code
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     * Lifted jumps to return sites
     */
    private String[] readRow() {
        if (this.input == null) {
            return null;
        }
        row = new ArrayList<String>();
        try {
            do lbl-1000: // 3 sources:
            {
                if ((v = this.readValue()) != null || !this.endOfLine) ** GOTO lbl10
                if (row.size() != 0) return row.toArray(new String[row.size()]);
                if (!this.endOfFile) ** GOTO lbl-1000
                return null;
lbl10: // 1 sources:
                row.add(v);
            } while (!this.endOfLine);
            return row.toArray(new String[row.size()]);
        }
        catch (IOException e) {
            throw new RuntimeException("IOException while reading", e);
        }
    }

    public void close() throws IOException {
        if (this.input != null) {
            this.input.close();
            this.input = null;
        }
        if (this.output != null) {
            this.output.close();
            this.output = null;
        }
    }

    public void setFieldSeparatorWrite(String fieldSeparatorWrite) {
        this.fieldSeparatorWrite = fieldSeparatorWrite;
    }

    public String getFieldSeparatorWrite() {
        return this.fieldSeparatorWrite;
    }

    public void setFieldSeparatorRead(char fieldSeparatorRead) {
        this.fieldSeparatorRead = fieldSeparatorRead;
    }

    public char getFieldSeparatorRead() {
        return this.fieldSeparatorRead;
    }

    public String getRowSeparatorWrite() {
        return this.rowSeparatorWrite;
    }

    public void setRowSeparatorWrite(String rowSeparatorWrite) {
        this.rowSeparatorWrite = rowSeparatorWrite;
    }

    public void setFieldDelimiter(char fieldDelimiter) {
        this.fieldDelimiter = fieldDelimiter;
    }

    public char getFieldDelimiter() {
        return this.fieldDelimiter;
    }

    public void setEscapeCharacter(char escapeCharacter) {
        this.escapeCharacter = escapeCharacter;
    }

    public char getEscapeCharacter() {
        return this.escapeCharacter;
    }

    public void setLineSeparator(String lineSeparator) {
        this.lineSeparator = lineSeparator;
    }

    public void setNullString(String nullString) {
        this.nullString = nullString;
    }

    public String getNullString() {
        return this.nullString;
    }

    class RowIterator
    implements Iterator<String[]> {
        private String[] current;

        RowIterator() {
            this.readNext();
        }

        private void readNext() {
            this.current = Csv.this.readRow();
        }

        @Override
        public boolean hasNext() {
            return this.current != null;
        }

        @Override
        public String[] next() {
            String[] r = this.current;
            this.readNext();
            return r;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

}