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

org.simpleflatmapper.csv.CsvReader Maven / Gradle / Ivy

package org.simpleflatmapper.csv;

import org.simpleflatmapper.csv.parser.CellConsumer;
import org.simpleflatmapper.csv.parser.CharConsumer;
import org.simpleflatmapper.csv.parser.NullCellConsumer;
import org.simpleflatmapper.csv.parser.StringArrayCellConsumer;
import org.simpleflatmapper.util.CheckedConsumer;
import org.simpleflatmapper.util.ErrorHelper;
import org.simpleflatmapper.util.Function;

import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;
//IFJAVA8_START
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
//IFJAVA8_END



public final class CsvReader implements Iterable {

	private final CharConsumer consumer;

	private final Function cellConsumerWrapper;

	public CsvReader(CharConsumer charConsumer) {
		this(charConsumer, null);
	}

	public CsvReader(CharConsumer charConsumer,  Function cellConsumerWrapper) {
		this.consumer = charConsumer;
		this.cellConsumerWrapper = cellConsumerWrapper;
	}

	/**
	 * parse cvs
     * @param cellConsumer the consumer that the parser will callback
	 * @param  the cell consumer type
     * @throws java.io.IOException if an io error occurs
     * @return the cell consumer
	 */
	public  CC parseAll(CC cellConsumer)
			throws IOException {
		_parseAll(wrapConsumer(cellConsumer));

		return cellConsumer;
	}


	private  void _parseAll(CC cellConsumer) throws IOException {
		do {
			consumer.consumeAllBuffer(cellConsumer);
		} while(consumer.next());

		consumer.finish(cellConsumer);
	}


	/**
	 * parse cvs
	 * @param cellConsumer the cell consumer
     * @return true if there was data consumed
	 * @throws IOException if io error occurs
	 */
	public boolean parseRow(CellConsumer cellConsumer)
			throws IOException {
		return _parseRow(wrapConsumer(cellConsumer));
	}

	private boolean _parseRow(CellConsumer cellConsumer) throws IOException {
		do {
			if (consumer.consumeToNextRow(cellConsumer)) {
				return true;
			}
		} while(consumer.next());

		consumer.finish(cellConsumer);
		return false;
	}


	public void skipRows(int n) throws IOException {
		_parseRows(NullCellConsumer.INSTANCE, n);
	}

	public  CC  parseRows(CC cellConsumer, int limit) throws IOException {
		_parseRows(wrapConsumer(cellConsumer), limit);
		return cellConsumer;
	}

	private  void _parseRows(CC cellConsumer, int limit) throws IOException {
		for(int i = 0; i < limit; i++) {
			_parseRow(cellConsumer);
		}
	}

	public > RH read(RH consumer) throws IOException {
		parseAll(toCellConsumer(consumer));
		return consumer;
	}

	public > RH read(RH consumer, int limit) throws IOException {
		parseRows(toCellConsumer(consumer), limit);
		return consumer;
	}

	private CellConsumer toCellConsumer(CheckedConsumer consumer) {
		return StringArrayCellConsumer.newInstance(consumer);
	}

	private CellConsumer wrapConsumer(CellConsumer cellConsumer) {
		if (cellConsumerWrapper == null) return cellConsumer;
		return cellConsumerWrapper.apply(cellConsumer);
	}


	@Override
	public Iterator iterator() {
		return new CsvStringArrayIterator(this);
	}

	//IFJAVA8_START
	public Stream stream() {
		return StreamSupport.stream(new CsvStringArraySpliterator(this), false);
	}

	private static class CsvStringArraySpliterator implements Spliterator {
		private final CsvReader reader;

		public CsvStringArraySpliterator(CsvReader csvReader) {
			this.reader = csvReader;
		}

		@Override
		public boolean tryAdvance(Consumer action) {
			try {
				return reader.parseRow(reader.toCellConsumer(action::accept));
			} catch (IOException e) {
               return ErrorHelper.rethrow(e);
			}
		}

		@Override
		public void forEachRemaining(Consumer action) {
			try {
				reader.parseAll(reader.toCellConsumer(action::accept));
			} catch (IOException e) {
                ErrorHelper.rethrow(e);
			}
		}

		@Override
		public Spliterator trySplit() {
			return null;
		}

		@Override
		public long estimateSize() {
			return Long.MAX_VALUE;
		}

		@Override
		public int characteristics() {
			return Spliterator.ORDERED | Spliterator.NONNULL;
		}
	}


	//IFJAVA8_END

    private static class CsvStringArrayIterator implements Iterator {

        private final CsvReader reader;
        private final CellConsumer cellConsumer;

        private boolean isFetched;
        private String[] value;

        @SuppressWarnings("unchecked")
        public CsvStringArrayIterator(CsvReader csvReader) {
            cellConsumer = csvReader.toCellConsumer(new CheckedConsumer() {
                @Override
                public void accept(String[] strings)  {
                    value = strings;
                }
            });
            reader = csvReader;
        }

        @Override
        public boolean hasNext() {
            fetch();
            return value != null;
        }

        private void fetch() {
            if (!isFetched) {
                try {
                    value = null;
                    reader.parseRow(cellConsumer);
                } catch (IOException e) {
                    ErrorHelper.rethrow(e);
                }
                isFetched = true;
            }
        }

        @Override
        public String[] next() {
            fetch();
            if (value == null) throw new NoSuchElementException();
            isFetched = false;
            return value;
        }

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy