View Javadoc
1   package de.dlr.shepard.data.timeseries.utilities;
2   
3   import jakarta.annotation.Nonnull;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.util.Objects;
7   import lombok.NonNull;
8   
9   public class CsvInputStream extends InputStream {
10  
11    @NonNull
12    private final CsvLineProvider lineProvider;
13  
14    private String lineBuffer;
15    private int lineBufferLen = 0;
16    private int lineBufferPos = 0;
17  
18    public CsvInputStream(@NonNull CsvLineProvider lineProvider) {
19      this.lineProvider = Objects.requireNonNull(lineProvider);
20      try {
21        readCSVLine();
22      } catch (IOException e) {
23        // Ignore, will be thrown again in read method
24      }
25    }
26  
27    @Override
28    public int read() throws IOException {
29      var remaining = checkBuffer();
30      if (remaining <= 0) return -1;
31  
32      return lineBuffer.charAt(lineBufferPos++);
33    }
34  
35    @Override
36    public int read(@Nonnull byte[] b, int off, int len) throws IOException {
37      var remaining = checkBuffer();
38      if (remaining <= 0) return -1;
39  
40      var strLen = Math.min(len, remaining);
41      System.arraycopy(lineBuffer.getBytes(), lineBufferPos, b, off, strLen);
42      lineBufferPos += strLen;
43      return strLen;
44    }
45  
46    @Override
47    public int available() throws IOException {
48      return lineBufferLen - lineBufferPos;
49    }
50  
51    private int checkBuffer() throws IOException {
52      // Check whether a new CSV line must be generated
53      if (lineBufferPos >= lineBufferLen || lineBufferLen <= 0) readCSVLine();
54  
55      if (lineBufferLen > 0 && lineBufferPos >= lineBufferLen) {
56        // It should be impossible to reach this
57        throw new IOException("Buffer overflow");
58      }
59      return lineBufferLen - lineBufferPos;
60    }
61  
62    private void readCSVLine() throws IOException {
63      lineBuffer = lineProvider.readCsvLine();
64      lineBufferLen = lineBuffer.length();
65      lineBufferPos = 0;
66    }
67  }