summaryrefslogtreecommitdiff
path: root/dslog/DslogReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'dslog/DslogReader.java')
-rw-r--r--dslog/DslogReader.java136
1 files changed, 96 insertions, 40 deletions
diff --git a/dslog/DslogReader.java b/dslog/DslogReader.java
index 73d7dc5..1c0af25 100644
--- a/dslog/DslogReader.java
+++ b/dslog/DslogReader.java
@@ -1,40 +1,16 @@
package dslog;
+import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
-import java.lang.UnsupportedOperationException;
import java.time.Duration;
import java.time.Instant;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
import java.util.stream.IntStream;
-class DslogReader implements Closeable {
- private final InputStream reader;
-
- public final int version;
- public final Instant startTime;
- private long i = 0;
-
- public DslogReader(InputStream reader) throws IOException {
- this.reader = reader;
- this.version = Read.i32(reader);
- switch (this.version) {
- case 0: // ????-???? 2012
- this.startTime = Read.LVTimestamp(reader);
- break;
- case 1: // ????-???? 2014
- this.startTime = Read.LVTimestamp(reader);
- break;
- case 2: // ????-2015
- throw new UnsupportedOperationException("TODO: DSLOG v2 support");
- case 3: // 2016-now
- this.startTime = Read.LVTimestamp(reader);
- break;
- default:
- throw new UnsupportedOperationException("DSLOG file version ("+this.version+") newer than log reader (3)");
- }
- }
-
+class DslogReader implements Closeable, Iterator<DslogReader.Entry> {
public static class Entry {
public Instant time;
@@ -62,14 +38,70 @@ class DslogReader implements Closeable {
public short pdpTemperature;
}
- /**
- * @see https://www.chiefdelphi.com/forums/showthread.php?t=104689
- */
- public Entry readEntry() throws IOException{
- switch (version) {
+ /*============================================================*\
+ || Primitive IO ||
+ \*============================================================*/
+
+ private final InputStream reader;
+ public DslogReader(InputStream reader) throws IOException {
+ if (!reader.markSupported()) {
+ reader = new BufferedInputStream(reader);
+ }
+ this.reader = reader;
+ }
+
+ private boolean atEOF() throws IOException {
+ reader.mark(2);
+ boolean eof = (reader.read() < 0);
+ reader.reset();
+ return eof;
+ }
+
+ /*============================================================*\
+ || Parsing ||
+ \*============================================================*/
+
+ private int m_version;
+ private boolean m_haveVersion = false;
+ public int version() throws IOException {
+ if (!m_haveVersion) {
+ m_version = Read.i32(reader);
+ m_haveVersion = true;
+ }
+ return m_version;
+ }
+
+ private Instant m_startTime;
+ public Instant startTime() throws IOException {
+ if (m_startTime == null) {
+ switch (version()) {
+ case 0: // ????-???? 2012
+ m_startTime = Read.LVTimestamp(reader);
+ break;
+ case 1: // ????-???? 2014
+ m_startTime = Read.LVTimestamp(reader);
+ break;
+ case 2: // ????-2015
+ throw new UnsupportedVersionException("DSLOG (TODO)", 2);
+ case 3: // 2016-now
+ m_startTime = Read.LVTimestamp(reader);
+ break;
+ default:
+ throw new UnsupportedVersionException("DSLOG", version(), 3);
+ }
+ }
+ return m_startTime;
+ }
+
+ private long i = 0;
+ public Entry readEntry() throws IOException {
+ if (atEOF()) {
+ return null;
+ }
+ switch (version()) {
case 0:
return new Entry() {{
- time = startTime.plusMillis(20*i++);
+ time = startTime().plusMillis(20*i++);
/* 0 = 0 */
/* 0+4= 4 */tripTime = Duration.ofNanos((long)(Read.f32(reader)*1000));
@@ -86,9 +118,7 @@ class DslogReader implements Closeable {
}};
case 1:
return new Entry() {{
- time = startTime.plusMillis(20*i++);
-
- time = startTime.plusMillis(20*i++);
+ time = startTime().plusMillis(20*i++);
/* 0 = 0 */
/* 0+4= 4 */tripTime = Duration.ofNanos((long)(Read.f32(reader)*1000));
@@ -104,10 +134,10 @@ class DslogReader implements Closeable {
/* 13+1=14 */lostPackets = Read.i8(reader);
}};
case 2:
- throw new UnsupportedOperationException("TODO: DSLOG v2 support");
+ throw new UnsupportedVersionException("DSLOG (TODO)", 2);
case 3:
return new Entry() {{
- time = startTime.plusMillis(20*i++);
+ time = startTime().plusMillis(20*i++);
// Read the 35-byte structure
// Read the 10 bytes of non-PDP data
@@ -147,10 +177,36 @@ class DslogReader implements Closeable {
/* 24+1=25 */pdpTemperature = Read.u8(reader);
}};
default:
- throw new UnsupportedOperationException("DSLOG file version newer than log reader");
+ throw new UnsupportedVersionException("DSLOG", version(), 3);
}
}
+ /*============================================================*\
+ || Interfaces ||
+ \*============================================================*/
+
+ private IOException m_err;
+ private Entry m_next;
+ public boolean hasNext() {
+ if (m_next == null) {
+ try {
+ m_next = readEntry();
+ } catch (IOException e) {
+ m_err = e;
+ }
+ }
+ return m_next != null;
+ }
+ public Entry next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return m_next;
+ }
+ public IOException err() {
+ return m_err;
+ }
+
public void close() throws IOException {
reader.close();
}