ExecutionDataReader.java revision cb3b5e12a69fb23d638e039f14ecb246210ec174
1/*******************************************************************************
2 * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
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.EOFException;
16import java.io.IOException;
17import java.io.InputStream;
18
19/**
20 * Deserialization of execution data from binary streams.
21 *
22 * @author Marc R. Hoffmann
23 * @version $Revision: $
24 */
25public class ExecutionDataReader {
26
27	private final CompactDataInput in;
28
29	private IExecutionDataVisitor executionDataVisitor;
30
31	/**
32	 * Creates a new reader based on the given input stream input.
33	 *
34	 * @param input
35	 *            input stream to read execution data from
36	 */
37	public ExecutionDataReader(final InputStream input) {
38		this.in = new CompactDataInput(input);
39	}
40
41	/**
42	 * Sets an listener for execution data.
43	 *
44	 * @param visitor
45	 */
46	public void setExecutionDataVisitor(final IExecutionDataVisitor visitor) {
47		this.executionDataVisitor = visitor;
48	}
49
50	/**
51	 * Reads all data and reports it to the corresponding visitors.
52	 *
53	 * @throws IOException
54	 *             might be thrown by the underlying input stream
55	 */
56	public void read() throws IOException {
57		try {
58			while (true) {
59				final byte block = in.readByte();
60				switch (block) {
61				case ExecutionDataWriter.BLOCK_HEADER:
62					readHeader();
63					break;
64				case ExecutionDataWriter.BLOCK_EXECUTIONDATA:
65					readExecutionData();
66					break;
67				default:
68					throw new IOException("Unknown block type "
69							+ Integer.toHexString(block));
70				}
71			}
72		} catch (final EOFException e) {
73			// expected at the end of the stream
74		}
75	}
76
77	private void readHeader() throws IOException {
78		final char version = in.readChar();
79		if (version != ExecutionDataWriter.FORMAT_VERSION) {
80			throw new IOException("Incompatible format version "
81					+ Integer.toHexString(version));
82		}
83	}
84
85	private void readExecutionData() throws IOException {
86		final long classid = in.readLong();
87		final boolean[][] blockdata = new boolean[in.readVarInt()][];
88		for (int i = 0; i < blockdata.length; i++) {
89			blockdata[i] = new boolean[in.readVarInt()];
90			for (int j = 0; j < blockdata[i].length; j++) {
91				blockdata[i][j] = in.readBoolean();
92			}
93		}
94		if (executionDataVisitor != null) {
95			executionDataVisitor.visitClassExecution(classid, blockdata);
96		}
97	}
98
99}
100