Commit | Line | Data |
---|---|---|
866e5b51 | 1 | /******************************************************************************* |
58129ff7 | 2 | * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others |
866e5b51 FC |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
4311ac8b MAL |
9 | * Contributors: |
10 | * Matthew Khouzam - Initial API and implementation | |
11 | * Simon Marchi - Initial API and implementation | |
58129ff7 | 12 | * Matthew Khouzam - Update for live trace reading support |
51173fa1 | 13 | * Bernd Hufmann - Add method to copy metadata file |
866e5b51 FC |
14 | *******************************************************************************/ |
15 | ||
f357bcd4 | 16 | package org.eclipse.tracecompass.ctf.core.trace; |
866e5b51 | 17 | |
d16bb0dd | 18 | import java.io.File; |
866e5b51 FC |
19 | import java.io.FileInputStream; |
20 | import java.io.FileNotFoundException; | |
21 | import java.io.FileReader; | |
22 | import java.io.IOException; | |
23 | import java.io.Reader; | |
24 | import java.io.StringReader; | |
25 | import java.nio.ByteBuffer; | |
26 | import java.nio.ByteOrder; | |
27 | import java.nio.channels.FileChannel; | |
d16bb0dd | 28 | import java.nio.charset.Charset; |
51173fa1 BH |
29 | import java.nio.file.FileSystems; |
30 | import java.nio.file.Files; | |
31 | import java.nio.file.Path; | |
d16bb0dd | 32 | import java.nio.file.StandardOpenOption; |
866e5b51 FC |
33 | import java.util.UUID; |
34 | ||
35 | import org.antlr.runtime.ANTLRReaderStream; | |
36 | import org.antlr.runtime.CommonTokenStream; | |
37 | import org.antlr.runtime.RecognitionException; | |
38 | import org.antlr.runtime.tree.CommonTree; | |
4b825d8b | 39 | import org.antlr.runtime.tree.RewriteCardinalityException; |
b1ea73b5 | 40 | import org.eclipse.tracecompass.common.core.NonNullUtils; |
680f9173 | 41 | import org.eclipse.tracecompass.ctf.core.CTFException; |
f357bcd4 AM |
42 | import org.eclipse.tracecompass.ctf.parser.CTFLexer; |
43 | import org.eclipse.tracecompass.ctf.parser.CTFParser; | |
44 | import org.eclipse.tracecompass.ctf.parser.CTFParser.parse_return; | |
b1ea73b5 | 45 | import org.eclipse.tracecompass.internal.ctf.core.event.metadata.CtfAntlrException; |
f357bcd4 | 46 | import org.eclipse.tracecompass.internal.ctf.core.event.metadata.IOStructGen; |
b1ea73b5 | 47 | import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException; |
1b638236 | 48 | import org.eclipse.tracecompass.internal.ctf.core.trace.Utils; |
866e5b51 FC |
49 | |
50 | /** | |
58129ff7 | 51 | * The CTF trace metadata TSDL file |
791072b0 | 52 | * |
d37aaa7f FC |
53 | * @version 1.0 |
54 | * @author Matthew Khouzam | |
55 | * @author Simon Marchi | |
866e5b51 FC |
56 | */ |
57 | public class Metadata { | |
58 | ||
59 | // ------------------------------------------------------------------------ | |
60 | // Constants | |
61 | // ------------------------------------------------------------------------ | |
0f1e85f9 | 62 | private static final String TEXT_ONLY_METADATA_HEADER_PREFIX = "/* CTF"; //$NON-NLS-1$ |
d16bb0dd BH |
63 | |
64 | private static final int PREVALIDATION_SIZE = 8; | |
866e5b51 | 65 | |
f068c622 MK |
66 | private static final int BITS_PER_BYTE = Byte.SIZE; |
67 | ||
866e5b51 FC |
68 | /** |
69 | * Name of the metadata file in the trace directory | |
70 | */ | |
0594c61c | 71 | private static final String METADATA_FILENAME = "metadata"; //$NON-NLS-1$ |
866e5b51 FC |
72 | |
73 | /** | |
74 | * Size of the metadata packet header, in bytes, computed by hand. | |
75 | */ | |
0594c61c | 76 | private static final int METADATA_PACKET_HEADER_SIZE = 37; |
866e5b51 FC |
77 | |
78 | // ------------------------------------------------------------------------ | |
79 | // Attributes | |
80 | // ------------------------------------------------------------------------ | |
81 | ||
866e5b51 FC |
82 | /** |
83 | * Byte order as detected when reading the TSDL magic number. | |
84 | */ | |
a67ad2a0 | 85 | private ByteOrder fDetectedByteOrder = null; |
866e5b51 FC |
86 | |
87 | /** | |
88 | * The trace file to which belongs this metadata file. | |
89 | */ | |
a67ad2a0 | 90 | private final CTFTrace fTrace; |
58129ff7 MK |
91 | |
92 | private IOStructGen fTreeParser; | |
866e5b51 FC |
93 | |
94 | // ------------------------------------------------------------------------ | |
95 | // Constructors | |
96 | // ------------------------------------------------------------------------ | |
97 | ||
98 | /** | |
99 | * Constructs a Metadata object. | |
aa572e22 | 100 | * |
866e5b51 FC |
101 | * @param trace |
102 | * The trace to which belongs this metadata file. | |
103 | */ | |
104 | public Metadata(CTFTrace trace) { | |
a67ad2a0 | 105 | fTrace = trace; |
58129ff7 | 106 | } |
866e5b51 | 107 | |
58129ff7 MK |
108 | /** |
109 | * For network streaming | |
58129ff7 MK |
110 | */ |
111 | public Metadata() { | |
a67ad2a0 | 112 | fTrace = new CTFTrace(); |
866e5b51 FC |
113 | } |
114 | ||
115 | // ------------------------------------------------------------------------ | |
116 | // Getters/Setters/Predicates | |
117 | // ------------------------------------------------------------------------ | |
118 | ||
119 | /** | |
120 | * Returns the ByteOrder that was detected while parsing the metadata. | |
aa572e22 | 121 | * |
866e5b51 FC |
122 | * @return The byte order. |
123 | */ | |
124 | public ByteOrder getDetectedByteOrder() { | |
a67ad2a0 | 125 | return fDetectedByteOrder; |
866e5b51 FC |
126 | } |
127 | ||
58129ff7 MK |
128 | /** |
129 | * Gets the parent trace | |
130 | * | |
131 | * @return the parent trace | |
58129ff7 MK |
132 | */ |
133 | public CTFTrace getTrace() { | |
a67ad2a0 | 134 | return fTrace; |
58129ff7 MK |
135 | } |
136 | ||
866e5b51 FC |
137 | // ------------------------------------------------------------------------ |
138 | // Operations | |
139 | // ------------------------------------------------------------------------ | |
140 | ||
141 | /** | |
142 | * Parse the metadata file. | |
aa572e22 | 143 | * |
680f9173 | 144 | * @throws CTFException |
be6df2d8 | 145 | * If there was a problem parsing the metadata |
866e5b51 | 146 | */ |
680f9173 | 147 | public void parseFile() throws CTFException { |
866e5b51 FC |
148 | |
149 | /* | |
150 | * Reader. It will contain a StringReader if we are using packet-based | |
151 | * metadata and it will contain a FileReader if we have text-based | |
152 | * metadata. | |
153 | */ | |
58129ff7 MK |
154 | |
155 | try (FileInputStream fis = new FileInputStream(getMetadataPath()); | |
156 | FileChannel metadataFileChannel = fis.getChannel(); | |
157 | /* Check if metadata is packet-based, if not it is text based */ | |
b1ea73b5 | 158 | Reader metadataTextInput = (isPacketBased(metadataFileChannel) ? readBinaryMetaData(metadataFileChannel) : new FileReader(getMetadataPath()));) { |
58129ff7 MK |
159 | |
160 | readMetaDataText(metadataTextInput); | |
68c9980d AM |
161 | |
162 | } catch (FileNotFoundException e) { | |
680f9173 | 163 | throw new CTFException("Cannot find metadata file!", e); //$NON-NLS-1$ |
58129ff7 | 164 | } catch (IOException | ParseException e) { |
680f9173 | 165 | throw new CTFException(e); |
58129ff7 MK |
166 | } catch (RecognitionException | RewriteCardinalityException e) { |
167 | throw new CtfAntlrException(e); | |
168 | } | |
169 | } | |
170 | ||
680f9173 | 171 | private Reader readBinaryMetaData(FileChannel metadataFileChannel) throws CTFException { |
58129ff7 MK |
172 | /* Create StringBuffer to receive metadata text */ |
173 | StringBuffer metadataText = new StringBuffer(); | |
174 | ||
175 | /* | |
176 | * Read metadata packet one by one, appending the text to the | |
177 | * StringBuffer | |
178 | */ | |
179 | MetadataPacketHeader packetHeader = readMetadataPacket( | |
180 | metadataFileChannel, metadataText); | |
181 | while (packetHeader != null) { | |
182 | packetHeader = readMetadataPacket(metadataFileChannel, | |
183 | metadataText); | |
184 | } | |
185 | ||
186 | /* Wrap the metadata string with a StringReader */ | |
187 | return new StringReader(metadataText.toString()); | |
188 | } | |
189 | ||
d16bb0dd | 190 | /** |
b1ea73b5 MK |
191 | * Executes a weak validation of the metadata. It checks if a file with name |
192 | * metadata exists and if one of the following conditions are met: | |
193 | * <ul> | |
194 | * <li>For text-only metadata, the file starts with "/* CTF" (without the | |
195 | * quotes)</li> | |
196 | * <li>For packet-based metadata, the file starts with correct magic number | |
197 | * </li> | |
198 | * </ul> | |
d16bb0dd BH |
199 | * |
200 | * @param path | |
201 | * path to CTF trace directory | |
202 | * @return <code>true</code> if pre-validation is ok else <code>false</code> | |
203 | * @throws CTFException | |
204 | * file channel cannot be created | |
205 | * @since 1.0 | |
206 | */ | |
207 | public static boolean preValidate(String path) throws CTFException { | |
208 | String metadataPath = path + Utils.SEPARATOR + METADATA_FILENAME; | |
209 | File metadataFile = new File(metadataPath); | |
210 | if (metadataFile.exists() && metadataFile.length() > PREVALIDATION_SIZE) { | |
211 | try (FileChannel fc = FileChannel.open(metadataFile.toPath(), StandardOpenOption.READ)) { | |
212 | ByteBuffer bb = ByteBuffer.allocate(PREVALIDATION_SIZE); | |
213 | bb.clear(); | |
214 | fc.read(bb); | |
215 | bb.flip(); | |
216 | if (bb.getInt(0) == Utils.TSDL_MAGIC) { | |
217 | return true; | |
218 | } | |
219 | bb.order(ByteOrder.LITTLE_ENDIAN); | |
220 | if (bb.getInt(0) == Utils.TSDL_MAGIC) { | |
221 | return true; | |
222 | } | |
223 | bb.position(0); | |
224 | Charset forName = Charset.forName("ASCII"); //$NON-NLS-1$ | |
225 | byte bytes[] = new byte[PREVALIDATION_SIZE]; | |
226 | bb.get(bytes); | |
227 | String text = new String(bytes, forName); | |
228 | return text.startsWith(TEXT_ONLY_METADATA_HEADER_PREFIX); | |
229 | } catch (IOException e) { | |
230 | throw new CTFException(e.getMessage(), e); | |
231 | } | |
232 | } | |
233 | return false; | |
234 | } | |
235 | ||
58129ff7 MK |
236 | /** |
237 | * Read the metadata from a formatted TSDL string | |
238 | * | |
239 | * @param data | |
240 | * the data to read | |
680f9173 | 241 | * @throws CTFException |
58129ff7 MK |
242 | * this exception wraps a ParseException, IOException or |
243 | * CtfAntlrException, three exceptions that can be obtained from | |
244 | * parsing a TSDL file | |
58129ff7 | 245 | */ |
680f9173 | 246 | public void parseText(String data) throws CTFException { |
58129ff7 MK |
247 | Reader metadataTextInput = new StringReader(data); |
248 | try { | |
249 | readMetaDataText(metadataTextInput); | |
250 | } catch (IOException | ParseException e) { | |
680f9173 | 251 | throw new CTFException(e); |
58129ff7 | 252 | } catch (RecognitionException | RewriteCardinalityException e) { |
950ee1f5 | 253 | throw new CtfAntlrException(e); |
58129ff7 MK |
254 | } |
255 | ||
256 | } | |
257 | ||
258 | private void readMetaDataText(Reader metadataTextInput) throws IOException, RecognitionException, ParseException { | |
259 | CommonTree tree = createAST(metadataTextInput); | |
260 | ||
261 | /* Generate IO structures (declarations) */ | |
b1ea73b5 | 262 | fTreeParser = new IOStructGen(tree, NonNullUtils.checkNotNull(fTrace)); |
58129ff7 | 263 | fTreeParser.generate(); |
a67ad2a0 MK |
264 | /* store locally in case of concurrent modification */ |
265 | ByteOrder detectedByteOrder = getDetectedByteOrder(); | |
266 | if (detectedByteOrder != null && fTrace.getByteOrder() != detectedByteOrder) { | |
0f1e85f9 MK |
267 | throw new ParseException("Metadata byte order and trace byte order inconsistent."); //$NON-NLS-1$ |
268 | } | |
58129ff7 MK |
269 | } |
270 | ||
271 | /** | |
272 | * Read a metadata fragment from a formatted TSDL string | |
273 | * | |
274 | * @param dataFragment | |
275 | * the data to read | |
680f9173 | 276 | * @throws CTFException |
58129ff7 MK |
277 | * this exception wraps a ParseException, IOException or |
278 | * CtfAntlrException, three exceptions that can be obtained from | |
279 | * parsing a TSDL file | |
58129ff7 | 280 | */ |
680f9173 | 281 | public void parseTextFragment(String dataFragment) throws CTFException { |
58129ff7 MK |
282 | Reader metadataTextInput = new StringReader(dataFragment); |
283 | try { | |
284 | readMetaDataTextFragment(metadataTextInput); | |
285 | } catch (IOException | ParseException e) { | |
680f9173 | 286 | throw new CTFException(e); |
58129ff7 | 287 | } catch (RecognitionException | RewriteCardinalityException e) { |
950ee1f5 | 288 | throw new CtfAntlrException(e); |
68c9980d | 289 | } |
866e5b51 FC |
290 | } |
291 | ||
58129ff7 MK |
292 | private void readMetaDataTextFragment(Reader metadataTextInput) throws IOException, RecognitionException, ParseException { |
293 | CommonTree tree = createAST(metadataTextInput); | |
294 | fTreeParser.setTree(tree); | |
295 | fTreeParser.generateFragment(); | |
296 | } | |
297 | ||
791072b0 MK |
298 | private static CommonTree createAST(Reader metadataTextInput) throws IOException, |
299 | RecognitionException { | |
300 | /* Create an ANTLR reader */ | |
301 | ANTLRReaderStream antlrStream; | |
302 | antlrStream = new ANTLRReaderStream(metadataTextInput); | |
303 | ||
304 | /* Parse the metadata text and get the AST */ | |
305 | CTFLexer ctfLexer = new CTFLexer(antlrStream); | |
306 | CommonTokenStream tokens = new CommonTokenStream(ctfLexer); | |
307 | CTFParser ctfParser = new CTFParser(tokens, false); | |
791072b0 | 308 | |
0594c61c | 309 | parse_return pr = ctfParser.parse(); |
bbbc7d98 | 310 | return pr.getTree(); |
791072b0 MK |
311 | } |
312 | ||
866e5b51 FC |
313 | /** |
314 | * Determines whether the metadata file is packet-based by looking at the | |
315 | * TSDL magic number. If it is packet-based, it also gives information about | |
316 | * the endianness of the trace using the detectedByteOrder attribute. | |
aa572e22 | 317 | * |
866e5b51 FC |
318 | * @param metadataFileChannel |
319 | * FileChannel of the metadata file. | |
320 | * @return True if the metadata is packet-based. | |
680f9173 | 321 | * @throws CTFException |
866e5b51 FC |
322 | */ |
323 | private boolean isPacketBased(FileChannel metadataFileChannel) | |
680f9173 | 324 | throws CTFException { |
866e5b51 | 325 | /* |
ecb12461 EB |
326 | * Create a ByteBuffer to read the TSDL magic number (default is |
327 | * big-endian) | |
866e5b51 FC |
328 | */ |
329 | ByteBuffer magicByteBuffer = ByteBuffer.allocate(Utils.TSDL_MAGIC_LEN); | |
330 | ||
331 | /* Read without changing file position */ | |
332 | try { | |
333 | metadataFileChannel.read(magicByteBuffer, 0); | |
334 | } catch (IOException e) { | |
680f9173 | 335 | throw new CTFException("Unable to read metadata file channel.", e); //$NON-NLS-1$ |
866e5b51 FC |
336 | } |
337 | ||
338 | /* Get the first int from the file */ | |
339 | int magic = magicByteBuffer.getInt(0); | |
340 | ||
341 | /* Check if it matches */ | |
342 | if (Utils.TSDL_MAGIC == magic) { | |
a67ad2a0 | 343 | fDetectedByteOrder = ByteOrder.BIG_ENDIAN; |
866e5b51 FC |
344 | return true; |
345 | } | |
346 | ||
ecb12461 | 347 | /* Try the same thing, but with little-endian */ |
866e5b51 FC |
348 | magicByteBuffer.order(ByteOrder.LITTLE_ENDIAN); |
349 | magic = magicByteBuffer.getInt(0); | |
350 | ||
351 | if (Utils.TSDL_MAGIC == magic) { | |
a67ad2a0 | 352 | fDetectedByteOrder = ByteOrder.LITTLE_ENDIAN; |
866e5b51 FC |
353 | return true; |
354 | } | |
355 | ||
356 | return false; | |
357 | } | |
358 | ||
58129ff7 MK |
359 | private String getMetadataPath() { |
360 | /* Path of metadata file = trace directory path + metadata filename */ | |
a67ad2a0 | 361 | if (fTrace.getTraceDirectory() == null) { |
d4a0dd35 | 362 | return ""; //$NON-NLS-1$ |
58129ff7 | 363 | } |
a67ad2a0 | 364 | return fTrace.getTraceDirectory().getPath() |
58129ff7 MK |
365 | + Utils.SEPARATOR + METADATA_FILENAME; |
366 | } | |
367 | ||
866e5b51 FC |
368 | /** |
369 | * Reads a metadata packet from the given metadata FileChannel, do some | |
370 | * basic validation and append the text to the StringBuffer. | |
aa572e22 | 371 | * |
866e5b51 FC |
372 | * @param metadataFileChannel |
373 | * Metadata FileChannel | |
374 | * @param metadataText | |
375 | * StringBuffer to which the metadata text will be appended. | |
376 | * @return A structure describing the header of the metadata packet, or null | |
377 | * if the end of the file is reached. | |
680f9173 | 378 | * @throws CTFException |
866e5b51 FC |
379 | */ |
380 | private MetadataPacketHeader readMetadataPacket( | |
381 | FileChannel metadataFileChannel, StringBuffer metadataText) | |
b1ea73b5 | 382 | throws CTFException { |
866e5b51 FC |
383 | /* Allocate a ByteBuffer for the header */ |
384 | ByteBuffer headerByteBuffer = ByteBuffer.allocate(METADATA_PACKET_HEADER_SIZE); | |
385 | ||
386 | /* Read the header */ | |
866e5b51 | 387 | try { |
950ee1f5 EB |
388 | int nbBytesRead = metadataFileChannel.read(headerByteBuffer); |
389 | ||
390 | /* Return null if EOF */ | |
391 | if (nbBytesRead < 0) { | |
392 | return null; | |
393 | } | |
394 | ||
395 | if (nbBytesRead != METADATA_PACKET_HEADER_SIZE) { | |
680f9173 | 396 | throw new CTFException("Error reading the metadata header."); //$NON-NLS-1$ |
950ee1f5 EB |
397 | } |
398 | ||
866e5b51 | 399 | } catch (IOException e) { |
680f9173 | 400 | throw new CTFException("Error reading the metadata header.", e); //$NON-NLS-1$ |
866e5b51 FC |
401 | } |
402 | ||
866e5b51 FC |
403 | /* Set ByteBuffer's position to 0 */ |
404 | headerByteBuffer.position(0); | |
405 | ||
406 | /* Use byte order that was detected with the magic number */ | |
a67ad2a0 | 407 | headerByteBuffer.order(fDetectedByteOrder); |
866e5b51 | 408 | |
373ab081 | 409 | MetadataPacketHeader header = new MetadataPacketHeader(headerByteBuffer); |
866e5b51 FC |
410 | |
411 | /* Check TSDL magic number */ | |
373ab081 | 412 | if (!header.isMagicValid()) { |
680f9173 | 413 | throw new CTFException("TSDL magic number does not match"); //$NON-NLS-1$ |
866e5b51 FC |
414 | } |
415 | ||
416 | /* Check UUID */ | |
a67ad2a0 MK |
417 | if (!fTrace.uuidIsSet()) { |
418 | fTrace.setUUID(header.getUuid()); | |
419 | } else if (!fTrace.getUUID().equals(header.getUuid())) { | |
680f9173 | 420 | throw new CTFException("UUID mismatch"); //$NON-NLS-1$ |
866e5b51 FC |
421 | } |
422 | ||
423 | /* Extract the text from the packet */ | |
f068c622 | 424 | int payloadSize = ((header.getContentSize() / BITS_PER_BYTE) - METADATA_PACKET_HEADER_SIZE); |
4311ac8b | 425 | if (payloadSize < 0) { |
680f9173 | 426 | throw new CTFException("Invalid metadata packet payload size."); //$NON-NLS-1$ |
4311ac8b | 427 | } |
f068c622 | 428 | int skipSize = (header.getPacketSize() - header.getContentSize()) / BITS_PER_BYTE; |
866e5b51 FC |
429 | |
430 | /* Read the payload + the padding in a ByteBuffer */ | |
431 | ByteBuffer payloadByteBuffer = ByteBuffer.allocateDirect(payloadSize | |
432 | + skipSize); | |
433 | try { | |
434 | metadataFileChannel.read(payloadByteBuffer); | |
435 | } catch (IOException e) { | |
680f9173 | 436 | throw new CTFException("Error reading metadata packet payload.", e); //$NON-NLS-1$ |
866e5b51 FC |
437 | } |
438 | payloadByteBuffer.rewind(); | |
439 | ||
440 | /* Read only the payload from the ByteBuffer into a byte array */ | |
441 | byte payloadByteArray[] = new byte[payloadByteBuffer.remaining()]; | |
442 | payloadByteBuffer.get(payloadByteArray, 0, payloadSize); | |
443 | ||
444 | /* Convert the byte array to a String */ | |
445 | String str = new String(payloadByteArray, 0, payloadSize); | |
446 | ||
447 | /* Append it to the existing metadata */ | |
448 | metadataText.append(str); | |
449 | ||
450 | return header; | |
451 | } | |
452 | ||
0594c61c | 453 | private static class MetadataPacketHeader { |
866e5b51 | 454 | |
f068c622 | 455 | private static final int UUID_SIZE = 16; |
373ab081 MK |
456 | private final int fMagic; |
457 | private final UUID fUuid; | |
458 | private final int fChecksum; | |
459 | private final int fContentSize; | |
460 | private final int fPacketSize; | |
461 | private final byte fCompressionScheme; | |
462 | private final byte fEncryptionScheme; | |
463 | private final byte fChecksumScheme; | |
464 | private final byte fCtfMajorVersion; | |
465 | private final byte fCtfMinorVersion; | |
466 | ||
467 | public MetadataPacketHeader(ByteBuffer headerByteBuffer) { | |
468 | /* Read from the ByteBuffer */ | |
469 | fMagic = headerByteBuffer.getInt(); | |
f068c622 | 470 | byte[] uuidBytes = new byte[UUID_SIZE]; |
373ab081 MK |
471 | headerByteBuffer.get(uuidBytes); |
472 | fUuid = Utils.makeUUID(uuidBytes); | |
473 | fChecksum = headerByteBuffer.getInt(); | |
474 | fContentSize = headerByteBuffer.getInt(); | |
475 | fPacketSize = headerByteBuffer.getInt(); | |
476 | fCompressionScheme = headerByteBuffer.get(); | |
477 | fEncryptionScheme = headerByteBuffer.get(); | |
478 | fChecksumScheme = headerByteBuffer.get(); | |
479 | fCtfMajorVersion = headerByteBuffer.get(); | |
480 | fCtfMinorVersion = headerByteBuffer.get(); | |
481 | } | |
482 | ||
483 | public boolean isMagicValid() { | |
484 | return fMagic == Utils.TSDL_MAGIC; | |
485 | } | |
486 | ||
487 | public UUID getUuid() { | |
488 | return fUuid; | |
489 | } | |
490 | ||
491 | public int getContentSize() { | |
492 | return fContentSize; | |
493 | } | |
494 | ||
495 | public int getPacketSize() { | |
496 | return fPacketSize; | |
497 | } | |
866e5b51 FC |
498 | |
499 | @Override | |
500 | public String toString() { | |
501 | /* Only for debugging, shouldn't be externalized */ | |
e291b8c8 | 502 | /* Therefore it cannot be covered by test cases */ |
866e5b51 | 503 | return "MetadataPacketHeader [magic=0x" //$NON-NLS-1$ |
373ab081 MK |
504 | + Integer.toHexString(fMagic) + ", uuid=" //$NON-NLS-1$ |
505 | + fUuid.toString() + ", checksum=" + fChecksum //$NON-NLS-1$ | |
506 | + ", contentSize=" + fContentSize + ", packetSize=" //$NON-NLS-1$ //$NON-NLS-2$ | |
507 | + fPacketSize + ", compressionScheme=" + fCompressionScheme //$NON-NLS-1$ | |
508 | + ", encryptionScheme=" + fEncryptionScheme //$NON-NLS-1$ | |
509 | + ", checksumScheme=" + fChecksumScheme //$NON-NLS-1$ | |
510 | + ", ctfMajorVersion=" + fCtfMajorVersion //$NON-NLS-1$ | |
511 | + ", ctfMinorVersion=" + fCtfMinorVersion + ']'; //$NON-NLS-1$ | |
866e5b51 FC |
512 | } |
513 | ||
514 | } | |
51173fa1 BH |
515 | |
516 | /** | |
517 | * Copies the metadata file to a destination directory. | |
b1ea73b5 | 518 | * |
51173fa1 | 519 | * @param path |
b1ea73b5 | 520 | * the destination directory |
51173fa1 BH |
521 | * @return the path to the target file |
522 | * @throws IOException | |
523 | * if an error occurred | |
524 | * | |
525 | * @since 1.0 | |
526 | */ | |
527 | public Path copyTo(final File path) throws IOException { | |
a67ad2a0 | 528 | Path source = FileSystems.getDefault().getPath(fTrace.getTraceDirectory().getAbsolutePath(), METADATA_FILENAME); |
51173fa1 BH |
529 | Path destPath = FileSystems.getDefault().getPath(path.getAbsolutePath()); |
530 | return Files.copy(source, destPath.resolve(source.getFileName())); | |
531 | } | |
866e5b51 | 532 | } |