summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-03-13 18:16:25 -0400
committerLuke Shumaker <lukeshu@lukeshu.com>2017-03-13 18:16:25 -0400
commit2c9c848ae275705ce315b6061cd06640834c9d9d (patch)
treec2a0a1b1a45fe1e88cbfc2fafd1ba01ededcb987
parentcf1ea6c1a28ec7bc4cc7b8cd0da8ad5f1011ac7c (diff)
lazy-parse the version and startTime
-rw-r--r--dslog/DseventsReader.java106
-rw-r--r--dslog/DslogReader.java136
-rw-r--r--dslog/Logdir.java6
-rw-r--r--dslog/Main.java4
-rw-r--r--dslog/PdplogReader.java45
-rw-r--r--dslog/UnsupportedVersionException.java12
6 files changed, 234 insertions, 75 deletions
diff --git a/dslog/DseventsReader.java b/dslog/DseventsReader.java
index 1f7afa7..4ae0215 100644
--- a/dslog/DseventsReader.java
+++ b/dslog/DseventsReader.java
@@ -1,42 +1,78 @@
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.Instant;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
-class DseventsReader implements Closeable {
- private final InputStream reader;
+class DseventsReader implements Closeable, Iterator<DseventsReader.Event> {
+ public static class Event {
+ public Instant time;
+ public String message;
+ }
- public final int version;
- public final Instant startTime;
+ /*============================================================*\
+ || Primitive IO ||
+ \*============================================================*/
+ private final InputStream reader;
public DseventsReader(InputStream reader) throws IOException {
+ if (!reader.markSupported()) {
+ reader = new BufferedInputStream(reader);
+ }
this.reader = reader;
- this.version = Read.i32(reader);
- switch (this.version) {
- case 0:
- throw new UnsupportedOperationException("TODO: DSEVENTS v0 support");
- case 1:
- case 2:
- case 3: // 2016-now
- this.startTime = Read.LVTimestamp(reader);
- break;
- default:
- throw new UnsupportedOperationException("DSEVENTS file version ("+this.version+") newer than log reader (3)");
+ }
+
+ 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;
}
- public static class Event {
- public Instant time;
- public String message;
+ private Instant m_startTime;
+ public Instant startTime() throws IOException {
+ if (m_startTime == null) {
+ switch (version()) {
+ case 0:
+ throw new UnsupportedVersionException("DSEVENTS (TODO)", 0);
+ case 1:
+ case 2:
+ case 3: // 2016-now
+ m_startTime = Read.LVTimestamp(reader);
+ break;
+ default:
+ throw new UnsupportedVersionException("DSEVENTS", version(), 3);
+ }
+ }
+ return m_startTime;
}
public Event readEvent() throws IOException{
- switch (version) {
+ startTime();
+ if (atEOF()) {
+ return null;
+ }
+ switch (version()) {
case 0:
- throw new UnsupportedOperationException("TODO: DSEVENTS v0 support");
+ throw new UnsupportedVersionException("DSEVENTS (TODO)", 0);
case 1:
case 2:
case 3:
@@ -45,10 +81,36 @@ class DseventsReader implements Closeable {
message = Read.LVString(reader);
}};
default:
- throw new UnsupportedOperationException("DSEVENTS file version newer than log reader");
+ throw new UnsupportedVersionException("DSEVENTS", version(), 3);
}
}
+ /*============================================================*\
+ || Interfaces ||
+ \*============================================================*/
+
+ private IOException m_err;
+ private Event m_next;
+ public boolean hasNext() {
+ if (m_next == null) {
+ try {
+ m_next = readEvent();
+ } catch (IOException e) {
+ m_err = e;
+ }
+ }
+ return m_next != null;
+ }
+ public Event next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return m_next;
+ }
+ public IOException err() {
+ return m_err;
+ }
+
public void close() throws IOException {
reader.close();
}
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();
}
diff --git a/dslog/Logdir.java b/dslog/Logdir.java
index 90661bb..b798757 100644
--- a/dslog/Logdir.java
+++ b/dslog/Logdir.java
@@ -42,7 +42,7 @@ class Logdir {
if (filename.endsWith(".dslog")) {
String setname = filename.substring(0, filename.lastIndexOf('.'));
try (DslogReader dslog = new DslogReader(Files.newInputStream(filepath))) {
- getSet(logsets, setname).dslog = ""+dslog.version;
+ getSet(logsets, setname).dslog = ""+dslog.version();
} catch (Exception e) {
getSet(logsets, setname).pdplog = "☠";
throw e;
@@ -50,7 +50,7 @@ class Logdir {
} else if (filename.endsWith(".dsevents")) {
String setname = filename.substring(0, filename.lastIndexOf('.'));
try (DseventsReader dsevents = new DseventsReader(Files.newInputStream(filepath))) {
- getSet(logsets, setname).dsevents = ""+dsevents.version;
+ getSet(logsets, setname).dsevents = ""+dsevents.version();
} catch (Exception e) {
getSet(logsets, setname).pdplog = "☠";
throw e;
@@ -58,7 +58,7 @@ class Logdir {
} else if (filename.endsWith(".pdplog")) {
String setname = filename.substring(0, filename.lastIndexOf('.'));
try (PdplogReader pdplog = new PdplogReader(Files.newInputStream(filepath))) {
- getSet(logsets, setname).pdplog = ""+pdplog.version;
+ getSet(logsets, setname).pdplog = ""+pdplog.version();
} catch (Exception e) {
getSet(logsets, setname).pdplog = "☠";
throw e;
diff --git a/dslog/Main.java b/dslog/Main.java
index 0c95c50..5ea1a64 100644
--- a/dslog/Main.java
+++ b/dslog/Main.java
@@ -14,8 +14,8 @@ class Main {
for (String filename : args) {
System.out.println("Filename: "+filename);
DslogReader file = new DslogReader(Files.newInputStream(Paths.get(filename)));
- System.out.println("Format Version: "+file.version);
- System.out.println("Start Time: "+file.startTime);
+ System.out.println("Format Version: "+file.version());
+ System.out.println("Start Time: "+file.startTime());
CsvWriter.Dslog2CSV(file, System.out);
}
}
diff --git a/dslog/PdplogReader.java b/dslog/PdplogReader.java
index 3df9c2b..2618101 100644
--- a/dslog/PdplogReader.java
+++ b/dslog/PdplogReader.java
@@ -1,25 +1,54 @@
package dslog;
+import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
-import java.lang.UnsupportedOperationException;
class PdplogReader implements Closeable {
- private final InputStream reader;
- public final int version;
+ /*============================================================*\
+ || Primitive IO ||
+ \*============================================================*/
+ private final InputStream reader;
public PdplogReader(InputStream reader) throws IOException {
+ if (!reader.markSupported()) {
+ reader = new BufferedInputStream(reader);
+ }
this.reader = reader;
- this.version = Read.i32(reader);
- switch (this.version) {
+ }
+
+ 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;
+ }
+
+ public void read() throws IOException {
+ switch (version()) {
case 0: // ????-????
- throw new UnsupportedOperationException("TODO: PDPLOG v0 support");
+ throw new UnsupportedVersionException("PDPLOG (TODO)", 0);
case 1: // ????-2015
- throw new UnsupportedOperationException("TODO: PDPLOG v1 support");
+ throw new UnsupportedVersionException("PDPLOG (TODO)", 1);
default:
- throw new UnsupportedOperationException("Unrecognized PDPLOG version: "+this.version);
+ throw new UnsupportedVersionException("PDPLOG", version(), 1);
}
}
diff --git a/dslog/UnsupportedVersionException.java b/dslog/UnsupportedVersionException.java
new file mode 100644
index 0000000..2667804
--- /dev/null
+++ b/dslog/UnsupportedVersionException.java
@@ -0,0 +1,12 @@
+package dslog;
+
+import java.io.IOException;
+
+class UnsupportedVersionException extends IOException {
+ public UnsupportedVersionException(String thing, int version) {
+ super("Unsupported file format version: "+thing+" v"+version);
+ }
+ public UnsupportedVersionException(String thing, int version, int cur) {
+ super("File format version ("+thing+" v"+version+") new that log reader ("+cur+")");
+ }
+}