001 /*
002 * Cobertura - http://cobertura.sourceforge.net/
003 *
004 * Copyright (C) 2006 Jiri Mares
005 *
006 * Cobertura is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published
008 * by the Free Software Foundation; either version 2 of the License,
009 * or (at your option) any later version.
010 *
011 * Cobertura is distributed in the hope that it will be useful, but
012 * WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with Cobertura; if not, write to the Free Software
018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019 * USA
020 */
021
022 package net.sourceforge.cobertura.coveragedata;
023
024 import java.io.Serializable;
025 import java.util.Arrays;
026
027 /**
028 * <p>
029 * This class implements HasBeenInstrumented so that when cobertura instruments
030 * itself, it will omit this class. It does this to avoid an infinite recursion
031 * problem because instrumented classes make use of this class.
032 * </p>
033 */
034 public class SwitchData implements BranchCoverageData, Comparable, Serializable,
035 HasBeenInstrumented
036 {
037 private static final long serialVersionUID = 9;
038
039 private int switchNumber;
040
041 private long defaultHits;
042
043 private long[] hits;
044
045 private int[] keys;
046
047 public SwitchData(int switchNumber, int[] keys)
048 {
049 super();
050 this.switchNumber = switchNumber;
051 defaultHits = 0;
052 hits = new long[keys.length];
053 Arrays.fill(hits, 0);
054 this.keys = new int[keys.length];
055 System.arraycopy(keys, 0, this.keys, 0, keys.length);
056 }
057
058 public SwitchData(int switchNumber, int min, int max)
059 {
060 super();
061 this.switchNumber = switchNumber;
062 defaultHits = 0;
063 hits = new long[max - min + 1];
064 Arrays.fill(hits, 0);
065 this.keys = new int[max - min + 1];
066 for (int i = 0; min <= max; keys[i++] = min++);
067 }
068
069 public SwitchData(int switchNumber)
070 {
071 this(switchNumber, new int[0]);
072 }
073
074 public int compareTo(Object o)
075 {
076 if (!o.getClass().equals(SwitchData.class))
077 return Integer.MAX_VALUE;
078 return this.switchNumber - ((SwitchData) o).switchNumber;
079 }
080
081 void touchBranch(int branch)
082 {
083 if (branch == -1)
084 defaultHits++;
085 else
086 {
087 if (hits.length <= branch)
088 {
089 long[] old = hits;
090 hits = new long[branch + 1];
091 System.arraycopy(old, 0, hits, 0, old.length);
092 Arrays.fill(hits, old.length, hits.length - 1, 0);
093 }
094 hits[branch]++;
095 }
096 }
097
098 public int getSwitchNumber()
099 {
100 return this.switchNumber;
101 }
102
103 public long getHits(int branch)
104 {
105 if (hits.length > branch)
106 return hits[branch];
107 return -1;
108 }
109
110 public long getDefaultHits()
111 {
112 return defaultHits;
113 }
114
115 public double getBranchCoverageRate()
116 {
117 int branches = hits.length + 1;
118 int hit = (defaultHits > 0) ? 1 : 0;
119 for (int i = hits.length - 1; i >= 0; hit += ((hits[i--] > 0) ? 1 : 0));
120 return ((double) hit) / branches;
121 }
122
123 public boolean equals(Object obj)
124 {
125 if (this == obj)
126 return true;
127 if ((obj == null) || !(obj.getClass().equals(this.getClass())))
128 return false;
129
130 SwitchData switchData = (SwitchData) obj;
131 return (this.defaultHits == switchData.defaultHits)
132 && (Arrays.equals(this.hits, switchData.hits))
133 && (this.switchNumber == switchData.switchNumber);
134 }
135
136 public int hashCode()
137 {
138 return this.switchNumber;
139 }
140
141 public int getNumberOfCoveredBranches()
142 {
143 int ret = (defaultHits > 0) ? 1 : 0;
144 for (int i = hits.length -1; i >= 0;i--)
145 {
146 if (hits[i] > 0) ret++;
147 }
148 return ret;
149 }
150
151 public int getNumberOfValidBranches()
152 {
153 return hits.length + 1;
154 }
155
156 public void merge(BranchCoverageData coverageData)
157 {
158 SwitchData switchData = (SwitchData) coverageData;
159 defaultHits += switchData.defaultHits;
160 for (int i = Math.min(hits.length, switchData.hits.length) - 1; i >= 0; i--)
161 hits[i] += switchData.hits[i];
162 if (switchData.hits.length > hits.length)
163 {
164 long[] old = hits;
165 hits = new long[switchData.hits.length];
166 System.arraycopy(old, 0, hits, 0, old.length);
167 System.arraycopy(switchData.hits, old.length, hits, old.length, hits.length - old.length);
168 }
169 if ((this.keys.length == 0) && (switchData.keys.length > 0))
170 this.keys = switchData.keys;
171 }
172
173 }