ExecutionDataWriter.java revision 6fc14d15bb5458c56d2a4ac4dbbefd4be2763a88
1/******************************************************************************* 2 * Copyright (c) 2009, 2010 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Marc R. Hoffmann - initial API and implementation 10 * 11 * $Id: $ 12 *******************************************************************************/ 13package org.jacoco.core.data; 14 15import java.io.ByteArrayOutputStream; 16import java.io.IOException; 17import java.io.OutputStream; 18 19/** 20 * Serialization of execution data into binary streams. 21 * 22 * @author Marc R. Hoffmann 23 * @version $Revision: $ 24 */ 25public class ExecutionDataWriter implements IExecutionDataVisitor { 26 27 /** File format version, will be incremented for each incompatible change. */ 28 public static final char FORMAT_VERSION = 0x1004; 29 30 /** Magic number in header for file format identification. */ 31 public static final char MAGIC_NUMBER = 0xC0C0; 32 33 /** Block identifier for file headers. */ 34 public static final byte BLOCK_HEADER = 0x01; 35 36 /** Block identifier for execution data of a single class. */ 37 public static final byte BLOCK_EXECUTIONDATA = 0x10; 38 39 private final CompactDataOutput out; 40 41 /** 42 * Creates a new writer based on the given output stream. Depending on the 43 * nature of the underlying stream output should be buffered as most data is 44 * written in single bytes. 45 * 46 * @param output 47 * binary stream to write execution data to 48 */ 49 public ExecutionDataWriter(final OutputStream output) { 50 this.out = new CompactDataOutput(output); 51 } 52 53 /** 54 * Writes an file header to identify the stream and its protocol version. 55 * 56 * @throws IOException 57 */ 58 public void writeHeader() throws IOException { 59 out.writeByte(BLOCK_HEADER); 60 out.writeChar(MAGIC_NUMBER); 61 out.writeChar(FORMAT_VERSION); 62 } 63 64 public void visitClassExecution(final long id, final String name, 65 final boolean[] data) { 66 try { 67 out.writeByte(BLOCK_EXECUTIONDATA); 68 out.writeLong(id); 69 out.writeUTF(name); 70 out.writeBooleanArray(data); 71 } catch (final IOException e) { 72 throw new RuntimeException(e); 73 } 74 } 75 76 /** 77 * Returns the first bytes of a file that represents a valid execution data 78 * file. In any case every execution data file starts with the three bytes 79 * <code>0x01 0xC0 0xC0</code>. 80 * 81 * @return first bytes of a execution data file 82 */ 83 public static final byte[] getFileHeader() { 84 final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 85 try { 86 new ExecutionDataWriter(buffer).writeHeader(); 87 } catch (final IOException e) { 88 // Must not happen with ByteArrayOutputStream 89 throw new RuntimeException(e); 90 } 91 return buffer.toByteArray(); 92 } 93 94} 95