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
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
53 if (lineBufferPos >= lineBufferLen || lineBufferLen <= 0) readCSVLine();
54
55 if (lineBufferLen > 0 && lineBufferPos >= lineBufferLen) {
56
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 }