traceevent: support opening traces with empty events

Change-Id: Id0d8cbdc8efe43b9973ac8d7b1926658a1f36259
Signed-off-by: Arnaud Fiorini <fiorini.arnaud@gmail.com>
Reviewed-on: https://git.eclipse.org/r/150065
Tested-by: CI Bot
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core.tests/src/org/eclipse/tracecompass/incubator/traceevent/core/tests/TraceEventTraceTest.java b/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core.tests/src/org/eclipse/tracecompass/incubator/traceevent/core/tests/TraceEventTraceTest.java
index 2b0c656..bc7bab0 100644
--- a/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core.tests/src/org/eclipse/tracecompass/incubator/traceevent/core/tests/TraceEventTraceTest.java
+++ b/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core.tests/src/org/eclipse/tracecompass/incubator/traceevent/core/tests/TraceEventTraceTest.java
@@ -25,6 +25,7 @@
 import org.eclipse.tracecompass.incubator.internal.traceevent.core.trace.TraceEventTrace;
 import org.eclipse.tracecompass.internal.provisional.jsontrace.core.trace.JsonTrace;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
 import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
 import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile;
@@ -300,4 +301,36 @@
         }
         assertEquals(8, eventCount);
     }
+
+    /**
+     * Test a trace with an empty event
+     *
+     * @throws TmfTraceException
+     *             should not happen
+     */
+    @Test
+    public void testEmptyEvent() throws TmfTraceException {
+        String path = "traces/empty_event.json";
+        int nbEvents = 2;
+        ITmfTimestamp startTime = TmfTimestamp.fromMicros(456123453L);
+        ITmfTimestamp endTime = TmfTimestamp.fromMicros(456123455L);
+        testTrace(path, nbEvents, startTime, endTime);
+
+        // Test the values of the first event.
+        ITmfTrace trace = new TraceEventTrace();
+        try {
+            trace.initTrace(null, path, ITmfEvent.class);
+            ITmfContext context = trace.seekEvent(0.0);
+            ITmfEvent event = trace.getNext(context);
+            ITmfEventField eventField = event.getContent();
+            assertEquals(1000000.0, eventField.getField("dur").getValue());
+            assertEquals("X", eventField.getField("ph").getValue());
+            assertEquals("event1", eventField.getField("name").getValue());
+            assertEquals("12", eventField.getField("pid").getValue());
+            assertEquals(12, eventField.getField("tid").getValue());
+            assertEquals(456123453000L, eventField.getField("ts").getValue());
+        } finally {
+            trace.dispose();
+        }
+    }
 }
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core.tests/traces/empty_event.json b/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core.tests/traces/empty_event.json
new file mode 100644
index 0000000..9483f75
--- /dev/null
+++ b/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core.tests/traces/empty_event.json
@@ -0,0 +1,20 @@
+[
+    {},
+    {
+        "ph":"X",
+        "name":"event1",
+        "pid":"12",
+        "tid": "12",
+        "ts":"456123453",
+        "dur":"1000"
+    },
+    {},
+    {
+        "ph":"X",
+        "name":"event2",
+        "pid":"13",
+        "tid": "13",
+        "ts":"456123455",
+        "dur":"2000"
+    }
+]
\ No newline at end of file
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core/src/org/eclipse/tracecompass/incubator/internal/traceevent/core/event/TraceEventField.java b/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core/src/org/eclipse/tracecompass/incubator/internal/traceevent/core/event/TraceEventField.java
index 304a838..58ae366 100644
--- a/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core/src/org/eclipse/tracecompass/incubator/internal/traceevent/core/event/TraceEventField.java
+++ b/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core/src/org/eclipse/tracecompass/incubator/internal/traceevent/core/event/TraceEventField.java
@@ -62,7 +62,9 @@
         Map<@NonNull String, @NonNull Object> argsMap = new HashMap<>();
         root = G_SON.fromJson(fieldsString, JsonObject.class);
         long ts = 0;
-
+        if (root.size() == 0) {
+            return null;
+        }
         Double tso = optDouble(root, ITraceEventConstants.TIMESTAMP);
         if (tso == Double.NaN) {
             return null;
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core/src/org/eclipse/tracecompass/incubator/internal/traceevent/core/trace/TraceEventTrace.java b/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core/src/org/eclipse/tracecompass/incubator/internal/traceevent/core/trace/TraceEventTrace.java
index 1ecc39f..a80741b 100644
--- a/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core/src/org/eclipse/tracecompass/incubator/internal/traceevent/core/trace/TraceEventTrace.java
+++ b/tracetypes/org.eclipse.tracecompass.incubator.traceevent.core/src/org/eclipse/tracecompass/incubator/internal/traceevent/core/trace/TraceEventTrace.java
@@ -263,7 +263,8 @@
                     while (nextJson != null) {
                         TraceEventField field = TraceEventField.parseJson(nextJson);
                         if (field == null) {
-                            return null;
+                            nextJson = readNextEventString(() -> fFileInput.read());
+                            continue;
                         }
                         if (field.getPhase() != 'M') {
                             return new TraceEventEvent(this, context.getRank(), field);
@@ -334,7 +335,9 @@
         public @Nullable String resolve(@NonNull ITmfEvent event) {
             if (event instanceof TraceEventEvent) {
                 TraceEventField field = ((TraceEventEvent) event).getField();
-                return fPidNames.get(field.getPid());
+                if (field.getPid() != null) {
+                    return fPidNames.get(field.getPid());
+                }
             }
             return null;
         }
@@ -349,7 +352,9 @@
         public @Nullable String resolve(@NonNull ITmfEvent event) {
             if (event instanceof TraceEventEvent) {
                 TraceEventField field = ((TraceEventEvent) event).getField();
-                return fTidNames.get(field.getTid());
+                if (field.getTid() != null) {
+                    return fTidNames.get(field.getTid());
+                }
             }
             return null;
         }