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

br.com.objectos.flat.FlatReader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2016 Objectos, Fábrica de Software LTDA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package br.com.objectos.flat;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.UncheckedIOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.stream.Stream;

import br.com.objectos.core.lang.Preconditions;
import br.com.objectos.flat.FlatEnum;
import br.com.objectos.flat.LocalDatePattern;
import br.com.objectos.flat.LocalDateTimePattern;

/**
 * @author [email protected] (Marcio Endo)
 */
public class FlatReader implements AutoCloseable {

  private final Reader reader;
  private final char[] buffer;

  private int index = 0;
  private int length = 0;

  private FlatReader(Reader reader, int size) {
    this.reader = reader;
    buffer = new char[size];
  }

  public static FlatReader open(InputStream in) {
    return open(in, 8192);
  }

  static FlatReader ofString(String string) {
    Objects.requireNonNull(string);
    return new FlatReader(new StringReader(string), string.length());
  }

  static FlatReader open(InputStream in, int size) {
    Objects.requireNonNull(in);
    return new FlatReader(new InputStreamReader(in), size);
  }

  @Override
  public void close() {
    try {
      reader.close();
    } catch (IOException e) {
      throw new UncheckedIOException(e);
    }
  }

  public double decimal(int precision, int scale) {
    try {
      String text = text(precision);
      if ("".equals(text)) {
        return Double.NaN;
      } else {
        long longValue = Long.parseLong(text);
        return longValue / Math.pow(10, scale);
      }
    } catch (NumberFormatException e) {
      return Double.NaN;
    }
  }

  public  & FlatEnum> E flatEnum(Class enumType, int length) {
    Objects.requireNonNull(enumType);
    String text = text(length);
    return FlatEnumParser.of(enumType).parse(text);
  }

  public int integer(int length) {
    try {
      String text = text(length);
      return Integer.parseInt(text);
    } catch (NumberFormatException e) {
      return 0;
    }
  }

  public LocalDate localDate(LocalDatePattern pattern) {
    String text = text(pattern.length());
    return pattern.parse(text);
  }

  public LocalDateTime localDateTime(LocalDateTimePattern pattern) {
    String text = text(pattern.length());
    return pattern.parse(text);
  }

  public FlatReader skip(int length) {
    text(length);
    return this;
  }

  public Stream stream() {
    return new FlatReaderIterator(this).stream();
  }

  public String text(int length) {
    Preconditions.checkArgument(length > 0);

    ensureBuffer();
    return insideBuffer(length)
        ? buildStringBuffer(length)
        : buildStringLoop(length);
  }

  FlatReader nextLine() {
    while (true) {
      if (endOfReader()) {
        return null;
      }

      if (endOfBuffer()) {
        fillBuffer();

        if (endOfReader()) {
          return null;
        }
      }

      boolean found = buffer[index++] == '\n';

      if (found) {
        if (endOfBuffer()) {
          fillBuffer();

          if (endOfReader()) {
            return null;
          }
        }
        return this;
      }
    }
  }

  private String buildStringBuffer(int length) {
    String res = new String(buffer, index, length);
    index += length;
    return res.trim();
  }

  private String buildStringLoop(int length) {
    char[] charArray = new char[length];
    int offset = 0;
    int remaining = length - offset;

    while (!endOfReader() && remaining > 0) {
      fillBufferIfNecessary();
      int toCopy = Math.min(remaining, buffer.length - index);
      System.arraycopy(buffer, index, charArray, offset, toCopy);
      index += toCopy;
      offset += toCopy;
      remaining -= toCopy;
    }

    return new String(charArray).trim();
  }

  private boolean endOfBuffer() {
    return index == length;
  }

  private boolean endOfReader() {
    return length < 0;
  }

  private void ensureBuffer() {
    if (endOfReader()) {
      return;
    }

    if (endOfBuffer()) {
      fillBuffer();
    }
  }

  private void fillBuffer() {
    try {
      index = 0;
      length = reader.read(buffer);
    } catch (IOException e) {
      throw new UncheckedIOException(e);
    }
  }

  private void fillBufferIfNecessary() {
    if (endOfBuffer()) {
      fillBuffer();
    }
  }

  private boolean insideBuffer(int length) {
    if (this.length < length) {
      return false;
    }

    return length <= this.length - index;
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy