ctf.core: Parse data stream of a trace Implement parsing of data streams for CTF2 Traces. Testing of this patch is postponed until after the follow-up patch [1]. [1]https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/203295 Change-Id: I6ce9273e46b1e970a77354346fb5814b061d2c81 Signed-off-by: Sehr Moosabhoy <sehr.moosabhoy@ericsson.com> Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/203294 Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org> Tested-by: Marco Miller <marco.miller@ericsson.com> Reviewed-by: Marco Miller <marco.miller@ericsson.com>
diff --git a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/CTFStreamInput.java b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/CTFStreamInput.java index 1aea251..5c4d80b 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/CTFStreamInput.java +++ b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/CTFStreamInput.java
@@ -17,6 +17,7 @@ import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode; import java.nio.file.StandardOpenOption; @@ -210,8 +211,9 @@ * The BitBuffer to extract data from the StreamInput */ BitBuffer bitBuffer = new BitBuffer(); - bitBuffer.setByteOrder(getStream().getTrace().getByteOrder()); + ByteOrder byteOrder = getStream().getTrace().getByteOrder(); + bitBuffer.setByteOrder(byteOrder); } /**
diff --git a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java index c50a939..eb11a90 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java +++ b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java
@@ -258,6 +258,9 @@ fragment = Objects.requireNonNull(gson.fromJson(jsonBlocks[i], JsonEventRecordMetadataNode.class)); } else if (type.equals(JsonMetadataStrings.FRAGMENT_DATA_STREAM)) { fragment = Objects.requireNonNull(gson.fromJson(jsonBlocks[i], JsonDataStreamMetadataNode.class)); + if (!jsonBlocks[i].contains("id:")) { //$NON-NLS-1$ + ((JsonDataStreamMetadataNode) fragment).setId(-1); + } } else if (type.equals(JsonMetadataStrings.FRAGMENT_FIELD_ALIAS)) { fragment = Objects.requireNonNull(gson.fromJson(jsonBlocks[i], JsonFieldClassAliasMetadataNode.class)); } @@ -271,8 +274,8 @@ } /** - * Checks the version of the CTF trace by reading the first JSON fragment - * if it is a CTF2 fragment it updates the major of the trace + * Checks the version of the CTF trace by reading the first JSON fragment if + * it is a CTF2 fragment it updates the major of the trace * * @throws CTFException * throws exception if file is invalid
diff --git a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java index 6a3d143..1063e7d 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java +++ b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java
@@ -151,7 +151,7 @@ } traceNode = child; parseTrace(traceNode); - } else if (CTFParser.tokenNames[CTFParser.STREAM].equals(type)) { + } else if (CTFParser.tokenNames[CTFParser.STREAM].equals(type) || JsonMetadataStrings.FRAGMENT_DATA_STREAM.equals(type)) { StreamParser.INSTANCE.parse(child, new StreamParser.Param(fTrace, fRoot)); hasStreams = true; } else if (CTFParser.tokenNames[CTFParser.EVENT].equals(type) || JsonMetadataStrings.FRAGMENT_EVENT_RECORD.equals(type)) {
diff --git a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonDataStreamMetadataNode.java b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonDataStreamMetadataNode.java index c3ae214..53b12ef 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonDataStreamMetadataNode.java +++ b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonDataStreamMetadataNode.java
@@ -118,6 +118,16 @@ return fEventRecordCommonContextClass; } + /** + * Set the id of this data stream + * + * @param id + * id of the data stream + */ + public void setId(int id) { + fId = id; + } + @Override public void initialize() throws CTFException { super.initialize();
diff --git a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/stream/StreamDeclarationParser.java b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/stream/StreamDeclarationParser.java index a8382fe..f35cc7a 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/stream/StreamDeclarationParser.java +++ b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/stream/StreamDeclarationParser.java
@@ -26,6 +26,9 @@ import org.eclipse.tracecompass.ctf.parser.CTFParser; import org.eclipse.tracecompass.internal.ctf.core.Activator; import org.eclipse.tracecompass.internal.ctf.core.event.metadata.AbstractScopedCommonTreeParser; +import org.eclipse.tracecompass.internal.ctf.core.event.metadata.CTFJsonMetadataNode; +import org.eclipse.tracecompass.internal.ctf.core.event.metadata.JsonDataStreamMetadataNode; +import org.eclipse.tracecompass.internal.ctf.core.event.metadata.JsonStructureFieldMetadataNode; import org.eclipse.tracecompass.internal.ctf.core.event.metadata.Messages; import org.eclipse.tracecompass.internal.ctf.core.event.metadata.MetadataStrings; import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException; @@ -138,97 +141,142 @@ CTFStream stream = ((Param) param).fStream; CTFTrace fTrace = ((Param) param).fTrace; - /* There should be a left and right */ + if (streamDecl instanceof CTFJsonMetadataNode) { + JsonDataStreamMetadataNode decl = (JsonDataStreamMetadataNode) streamDecl; - ICTFMetadataNode leftNode = streamDecl.getChild(0); - ICTFMetadataNode rightNode = streamDecl.getChild(1); - - List<ICTFMetadataNode> leftStrings = leftNode.getChildren(); - - if (!isAnyUnaryString(leftStrings.get(0))) { - throw new ParseException(IDENTIFIER_MUST_BE_A_STRING); - } - - String left = concatenateUnaryStrings(leftStrings); - - if (left.equals(MetadataStrings.ID)) { - if (stream.isIdSet()) { - throw new ParseException(STREAM_ID + ALREADY_DEFINED); + if (decl.getId() >= 0) { + long streamId = decl.getId(); + stream.setId(streamId); } - long streamID = StreamIdParser.INSTANCE.parse(rightNode, null); - - stream.setId(streamID); - } else if (left.equals(MetadataStrings.EVENT_HEADER)) { - if (stream.isEventHeaderSet()) { - throw new ParseException(EVENT_HEADER + ALREADY_DEFINED); + JsonStructureFieldMetadataNode eventHeader = decl.getEventRecordHeaderClass(); + if (eventHeader != null) { + IDeclaration eventHeaderDecl = TypeSpecifierListParser.INSTANCE.parse(eventHeader, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); + DeclarationScope eventHeaderScope = lookupStructName(eventHeader, scope); + verifyEventHeaderScope(eventHeaderScope); + setEventHeader(stream, eventHeaderDecl); } - ICTFMetadataNode typeSpecifier = rightNode.getChild(0); - - if (!(CTFParser.tokenNames[CTFParser.TYPE_SPECIFIER_LIST].equals(typeSpecifier.getType()))) { - throw new ParseException(EVENT_HEADER + EXPECTS_A_TYPE_SPECIFIER); + JsonStructureFieldMetadataNode eventContext = decl.getEventRecordCommonContextClass(); + if (eventContext != null) { + IDeclaration eventContextDecl = TypeSpecifierListParser.INSTANCE.parse(eventContext, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); + verifyEventContext(eventContextDecl); + stream.setEventContext((StructDeclaration) eventContextDecl); } - IDeclaration eventHeaderDecl = TypeSpecifierListParser.INSTANCE.parse(typeSpecifier, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); - DeclarationScope eventHeaderScope = lookupStructName(typeSpecifier, scope); - if (eventHeaderScope == null) { - throw new ParseException(EVENT_HEADER + SCOPE_NOT_FOUND); + JsonStructureFieldMetadataNode packetContext = decl.getPacketContextFieldClass(); + if (packetContext != null) { + IDeclaration packetContextDecl = TypeSpecifierListParser.INSTANCE.parse(packetContext, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); + verifyPacketContext(packetContextDecl); + stream.setPacketContext((StructDeclaration) packetContextDecl); } - DeclarationScope eventScope = new DeclarationScope(scope, MetadataStrings.EVENT); - eventHeaderScope.setName(CTFStrings.HEADER); - eventScope.addChild(eventHeaderScope); - - if (eventHeaderDecl instanceof StructDeclaration) { - stream.setEventHeader((StructDeclaration) eventHeaderDecl); - } else if (eventHeaderDecl instanceof IEventHeaderDeclaration) { - stream.setEventHeader((IEventHeaderDeclaration) eventHeaderDecl); - } else { - throw new ParseException(EVENT_HEADER + EXPECTS_A_STRUCT); - } - - } else if (left.equals(MetadataStrings.EVENT_CONTEXT)) { - if (stream.isEventContextSet()) { - throw new ParseException(EVENT_CONTEXT + ALREADY_DEFINED); - } - - ICTFMetadataNode typeSpecifier = rightNode.getChild(0); - - if (!(CTFParser.tokenNames[CTFParser.TYPE_SPECIFIER_LIST].equals(typeSpecifier.getType()))) { - throw new ParseException(EVENT_CONTEXT + EXPECTS_A_TYPE_SPECIFIER); - } - - IDeclaration eventContextDecl = TypeSpecifierListParser.INSTANCE.parse(typeSpecifier, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); - - if (!(eventContextDecl instanceof StructDeclaration)) { - throw new ParseException(EVENT_CONTEXT + EXPECTS_A_STRUCT); - } - - stream.setEventContext((StructDeclaration) eventContextDecl); - } else if (left.equals(MetadataStrings.PACKET_CONTEXT)) { - if (stream.isPacketContextSet()) { - throw new ParseException(PACKET_CONTEXT + ALREADY_DEFINED); - } - - ICTFMetadataNode typeSpecifier = rightNode.getChild(0); - - if (!(CTFParser.tokenNames[CTFParser.TYPE_SPECIFIER_LIST].equals(typeSpecifier.getType()))) { - throw new ParseException(PACKET_CONTEXT + EXPECTS_A_TYPE_SPECIFIER); - } - - IDeclaration packetContextDecl = TypeSpecifierListParser.INSTANCE.parse(typeSpecifier, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); - - if (!(packetContextDecl instanceof StructDeclaration)) { - throw new ParseException(PACKET_CONTEXT + EXPECTS_A_STRUCT); - } - - stream.setPacketContext((StructDeclaration) packetContextDecl); } else { - Activator.log(IStatus.WARNING, Messages.IOStructGen_UnknownStreamAttributeWarning + ' ' + left); + /* There should be a left and right */ + + ICTFMetadataNode leftNode = streamDecl.getChild(0); + ICTFMetadataNode rightNode = streamDecl.getChild(1); + + List<ICTFMetadataNode> leftStrings = leftNode.getChildren(); + + if (!isAnyUnaryString(leftStrings.get(0))) { + throw new ParseException(IDENTIFIER_MUST_BE_A_STRING); + } + + String left = concatenateUnaryStrings(leftStrings); + + if (left.equals(MetadataStrings.ID)) { + if (stream.isIdSet()) { + throw new ParseException(STREAM_ID + ALREADY_DEFINED); + } + + long streamID = StreamIdParser.INSTANCE.parse(rightNode, null); + + stream.setId(streamID); + } else if (left.equals(MetadataStrings.EVENT_HEADER)) { + if (stream.isEventHeaderSet()) { + throw new ParseException(EVENT_HEADER + ALREADY_DEFINED); + } + + ICTFMetadataNode typeSpecifier = rightNode.getChild(0); + + if (!(CTFParser.tokenNames[CTFParser.TYPE_SPECIFIER_LIST].equals(typeSpecifier.getType()))) { + throw new ParseException(EVENT_HEADER + EXPECTS_A_TYPE_SPECIFIER); + } + + IDeclaration eventHeaderDecl = TypeSpecifierListParser.INSTANCE.parse(typeSpecifier, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); + DeclarationScope eventHeaderScope = lookupStructName(typeSpecifier, scope); + DeclarationScope eventScope = new DeclarationScope(scope, MetadataStrings.EVENT); + verifyEventHeaderScope(eventHeaderScope); + eventHeaderScope.setName(CTFStrings.HEADER); + eventScope.addChild(eventHeaderScope); + setEventHeader(stream, eventHeaderDecl); + } else if (left.equals(MetadataStrings.EVENT_CONTEXT)) { + if (stream.isEventContextSet()) { + throw new ParseException(EVENT_CONTEXT + ALREADY_DEFINED); + } + + ICTFMetadataNode typeSpecifier = rightNode.getChild(0); + + if (!(CTFParser.tokenNames[CTFParser.TYPE_SPECIFIER_LIST].equals(typeSpecifier.getType()))) { + throw new ParseException(EVENT_CONTEXT + EXPECTS_A_TYPE_SPECIFIER); + } + + IDeclaration eventContextDecl = TypeSpecifierListParser.INSTANCE.parse(typeSpecifier, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); + + verifyEventContext(eventContextDecl); + + stream.setEventContext((StructDeclaration) eventContextDecl); + } else if (left.equals(MetadataStrings.PACKET_CONTEXT)) { + if (stream.isPacketContextSet()) { + throw new ParseException(PACKET_CONTEXT + ALREADY_DEFINED); + } + + ICTFMetadataNode typeSpecifier = rightNode.getChild(0); + + if (!(CTFParser.tokenNames[CTFParser.TYPE_SPECIFIER_LIST].equals(typeSpecifier.getType()))) { + throw new ParseException(PACKET_CONTEXT + EXPECTS_A_TYPE_SPECIFIER); + } + + IDeclaration packetContextDecl = TypeSpecifierListParser.INSTANCE.parse(typeSpecifier, new TypeSpecifierListParser.Param(fTrace, null, null, scope)); + + verifyPacketContext(packetContextDecl); + + stream.setPacketContext((StructDeclaration) packetContextDecl); + } else { + Activator.log(IStatus.WARNING, Messages.IOStructGen_UnknownStreamAttributeWarning + ' ' + left); + } } return stream; } + private static void verifyPacketContext(IDeclaration packetContextDecl) throws ParseException { + if (!(packetContextDecl instanceof StructDeclaration)) { + throw new ParseException(PACKET_CONTEXT + EXPECTS_A_STRUCT); + } + } + + private static void verifyEventContext(IDeclaration eventContextDecl) throws ParseException { + if (!(eventContextDecl instanceof StructDeclaration)) { + throw new ParseException(EVENT_CONTEXT + EXPECTS_A_STRUCT); + } + } + + private static void verifyEventHeaderScope(DeclarationScope eventHeaderScope) throws ParseException { + if (eventHeaderScope == null) { + throw new ParseException(EVENT_HEADER + SCOPE_NOT_FOUND); + } + } + + private static void setEventHeader(CTFStream stream, IDeclaration eventHeaderDecl) throws ParseException { + if (eventHeaderDecl instanceof StructDeclaration) { + stream.setEventHeader((StructDeclaration) eventHeaderDecl); + } else if (eventHeaderDecl instanceof IEventHeaderDeclaration) { + stream.setEventHeader((IEventHeaderDeclaration) eventHeaderDecl); + } else { + throw new ParseException(EVENT_HEADER + EXPECTS_A_STRUCT); + } + } + private static DeclarationScope lookupStructName(ICTFMetadataNode typeSpecifier, DeclarationScope scope) { /* * This needs a struct.struct_name.name to work, luckily, that is 99.99%
diff --git a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/stream/StreamParser.java b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/stream/StreamParser.java index 44f5272..3b324df 100644 --- a/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/stream/StreamParser.java +++ b/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/stream/StreamParser.java
@@ -20,6 +20,7 @@ import org.eclipse.tracecompass.ctf.core.trace.CTFTrace; import org.eclipse.tracecompass.ctf.parser.CTFParser; import org.eclipse.tracecompass.internal.ctf.core.event.metadata.AbstractScopedCommonTreeParser; +import org.eclipse.tracecompass.internal.ctf.core.event.metadata.CTFJsonMetadataNode; import org.eclipse.tracecompass.internal.ctf.core.event.metadata.MetadataStrings; import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException; import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.TypeAliasParser; @@ -92,23 +93,28 @@ CTFTrace trace = ((Param) param).fTrace; CTFStream stream = new CTFStream(trace); - List<ICTFMetadataNode> children = streamNode.getChildren(); - if (children == null) { - throw new ParseException("Empty stream block"); //$NON-NLS-1$ - } - DeclarationScope scope = new DeclarationScope(parameter.fCurrentScope, MetadataStrings.STREAM); - for (ICTFMetadataNode child : children) { - String type = child.getType(); - if (CTFParser.tokenNames[CTFParser.TYPEALIAS].equals(type)) { - TypeAliasParser.INSTANCE.parse(child, new TypeAliasParser.Param(trace, scope)); - } else if (CTFParser.tokenNames[CTFParser.TYPEDEF].equals(type)) { - TypedefParser.INSTANCE.parse(child, new TypedefParser.Param(trace, scope)); - } else if (CTFParser.tokenNames[CTFParser.CTF_EXPRESSION_TYPE].equals(type) || CTFParser.tokenNames[CTFParser.CTF_EXPRESSION_VAL].equals(type)) { - StreamDeclarationParser.INSTANCE.parse(child, new StreamDeclarationParser.Param(trace, stream, scope)); - } else { - throw childTypeError(child); + if (streamNode instanceof CTFJsonMetadataNode) { + StreamDeclarationParser.INSTANCE.parse(streamNode, new StreamDeclarationParser.Param(trace, stream, scope)); + } else { + List<ICTFMetadataNode> children = streamNode.getChildren(); + + if (children == null) { + throw new ParseException("Empty stream block"); //$NON-NLS-1$ + } + + for (ICTFMetadataNode child : children) { + String type = child.getType(); + if (CTFParser.tokenNames[CTFParser.TYPEALIAS].equals(type)) { + TypeAliasParser.INSTANCE.parse(child, new TypeAliasParser.Param(trace, scope)); + } else if (CTFParser.tokenNames[CTFParser.TYPEDEF].equals(type)) { + TypedefParser.INSTANCE.parse(child, new TypedefParser.Param(trace, scope)); + } else if (CTFParser.tokenNames[CTFParser.CTF_EXPRESSION_TYPE].equals(type) || CTFParser.tokenNames[CTFParser.CTF_EXPRESSION_VAL].equals(type)) { + StreamDeclarationParser.INSTANCE.parse(child, new StreamDeclarationParser.Param(trace, stream, scope)); + } else { + throw childTypeError(child); + } } }