aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataDelegate.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.jacoco.core/src/org/jacoco/core/data/ExecutionDataDelegate.java')
-rw-r--r--org.jacoco.core/src/org/jacoco/core/data/ExecutionDataDelegate.java197
1 files changed, 197 insertions, 0 deletions
diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataDelegate.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataDelegate.java
new file mode 100644
index 00000000..7cbe989f
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataDelegate.java
@@ -0,0 +1,197 @@
+// BEGIN android-change
+package org.jacoco.core.data;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+/**
+ * Class that delegates calls to {@link IExecutionData} interface methods to another instance.
+ * Also has the ability to convert the underlying implementation to a {@link MappedExecutionData}
+ * instance.
+ */
+public class ExecutionDataDelegate implements IExecutionData {
+ private IExecutionData delegate;
+
+ public ExecutionDataDelegate(
+ final long id, final String name, final int probeCount, final FileChannel channel) {
+ if ((channel != null) && canMapData(name)) {
+ try {
+ delegate = new MappedExecutionData(id, name, probeCount, channel);
+ } catch (IOException e) {
+ delegate = new ExecutionData(id, name, probeCount);
+ }
+ } else {
+ delegate = new ExecutionData(id, name, probeCount);
+ }
+ }
+
+ /**
+ * Converts the existing delegate into a {@link MappedExecutionData} instance if it is not
+ * already one, and copies any probe data into the new instance.
+ */
+ public synchronized void convert(final FileChannel channel) throws IOException {
+ if (!(delegate instanceof MappedExecutionData) && canMapData(getName())) {
+ IExecutionData newDelegate = new MappedExecutionData(
+ getId(), getName(), getProbeCount(), channel);
+ newDelegate.merge(delegate);
+ delegate = newDelegate;
+ }
+ }
+
+ /**
+ * Determines if a class can be converted to memory-mapped.
+ */
+ private static boolean canMapData(final String name) {
+ if (name.startsWith("android/app/")
+ || name.startsWith("android/os/")
+ || name.startsWith("com/android/internal/util/")
+ || name.startsWith("java/")) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return the unique identifier for this class. The identifier is the CRC64
+ * checksum of the raw class file definition.
+ *
+ * @return class identifier
+ */
+ public long getId() {
+ return delegate.getId();
+ }
+
+ /**
+ * The VM name of the class.
+ *
+ * @return VM name
+ */
+ public String getName() {
+ return delegate.getName();
+ }
+
+ /**
+ * The number of instrumentation probes for this class.
+ *
+ * @return number of probes
+ */
+ public int getProbeCount() {
+ return delegate.getProbeCount();
+ }
+
+ /**
+ * Returns a copy of the probe data as a boolean array.
+ *
+ * Changes to the returned array will not be reflected in the execution data.
+ *
+ * @return copy of the probe data
+ */
+ public boolean[] getProbesCopy() {
+ return delegate.getProbesCopy();
+ }
+
+ /**
+ * Sets all probes to <code>false</code>.
+ */
+ public void reset() {
+ delegate.reset();
+ }
+
+ /**
+ * Checks whether any probe has been hit.
+ *
+ * @return <code>true</code>, if at least one probe has been hit
+ */
+ public boolean hasHits() {
+ return delegate.hasHits();
+ }
+
+ /**
+ * Merges the given execution data into the probe data of this object. I.e.
+ * a probe entry in this object is marked as executed (<code>true</code>) if
+ * this probe or the corresponding other probe was executed. So the result
+ * is
+ *
+ * <pre>
+ * A or B
+ * </pre>
+ *
+ * The probe array of the other object is not modified.
+ *
+ * @param other
+ * execution data to merge
+ */
+ public void merge(final IExecutionData other) {
+ delegate.merge(other);
+ }
+
+ /**
+ * Merges the given execution data into the probe data of this object. A
+ * probe in this object is set to the value of <code>flag</code> if the
+ * corresponding other probe was executed. For <code>flag==true</code> this
+ * corresponds to
+ *
+ * <pre>
+ * A or B
+ * </pre>
+ *
+ * For <code>flag==false</code> this can be considered as a subtraction
+ *
+ * <pre>
+ * A and not B
+ * </pre>
+ *
+ * The probe array of the other object is not modified.
+ *
+ * @param other
+ * execution data to merge
+ * @param flag
+ * merge mode
+ */
+ public void merge(final IExecutionData other, boolean flag) {
+ delegate.merge(other, flag);
+ }
+
+ /**
+ * Asserts that this execution data object is compatible with the given
+ * parameters. The purpose of this check is to detect a very unlikely class
+ * id collision.
+ *
+ * @param id
+ * other class id, must be the same
+ * @param name
+ * other name, must be equal to this name
+ * @param probecount
+ * probe data length, must be the same as for this data
+ * @throws IllegalStateException
+ * if the given parameters do not match this instance
+ */
+ public void assertCompatibility(final long id, final String name, final int probeCount)
+ throws IllegalStateException {
+ delegate.assertCompatibility(id, name, probeCount);
+ }
+
+ /**
+ * Returns the execution data probe for a given index. A value of
+ * <code>true</code> indicates that the corresponding probe was
+ * executed.
+ *
+ * @param index the probe's index to look up
+ *
+ * @return probe data
+ */
+ public boolean getProbe(final int index) {
+ return delegate.getProbe(index);
+ }
+
+ /**
+ * Sets the execution data probe at the given index to <code>true</code>.
+ *
+ * @param index the probe's index to set
+ * @param value the value to set the probe to
+ */
+ public void setProbe(final int index) {
+ delegate.setProbe(index);
+ }
+ }
+ // END android-change