HyphenationTree.java

1
/*
2
 * Copyright 1999-2004 The Apache Software Foundation.
3
 * 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 * 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 * 
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
/* $Id: HyphenationTree.java 3117 2008-01-31 05:53:22Z xlv $ */
18
 
19
package com.lowagie.text.pdf.hyphenation;
20
21
import java.io.InputStream;
22
import java.util.ArrayList;
23
import java.util.HashMap;
24
25
/**
26
 * This tree structure stores the hyphenation patterns in an efficient
27
 * way for fast lookup. It provides the provides the method to
28
 * hyphenate a word.
29
 *
30
 * @author Carlos Villegas <cav@uniscope.co.jp>
31
 */
32
public class HyphenationTree extends TernaryTree 
33
            implements PatternConsumer {
34
35
    private static final long serialVersionUID = -7763254239309429432L;
36
37
    /**
38
     * value space: stores the interletter values
39
     */
40
    protected ByteVector vspace;
41
42
    /**
43
     * This map stores hyphenation exceptions
44
     */
45
    protected HashMap stoplist;
46
47
    /**
48
     * This map stores the character classes
49
     */
50
    protected TernaryTree classmap;
51
52
    /**
53
     * Temporary map to store interletter values on pattern loading.
54
     */
55
    private transient TernaryTree ivalues;
56
57
    public HyphenationTree() {
58
        stoplist = new HashMap(23);    // usually a small table
59
        classmap = new TernaryTree();
60
        vspace = new ByteVector();
61
        vspace.alloc(1);    // this reserves index 0, which we don't use
62
    }
63
64
    /**
65
     * Packs the values by storing them in 4 bits, two values into a byte
66
     * Values range is from 0 to 9. We use zero as terminator,
67
     * so we'll add 1 to the value.
68
     * @param values a string of digits from '0' to '9' representing the
69
     * interletter values.
70
     * @return the index into the vspace array where the packed values
71
     * are stored.
72
     */
73
    protected int packValues(String values) {
74
        int i, n = values.length();
75 6 1. packValues : Replaced bitwise AND with OR → NO_COVERAGE
2. packValues : Replaced Shift Right with Shift Left → NO_COVERAGE
3. packValues : Replaced integer addition with subtraction → NO_COVERAGE
4. packValues : Replaced Shift Right with Shift Left → NO_COVERAGE
5. packValues : Replaced integer addition with subtraction → NO_COVERAGE
6. packValues : negated conditional → NO_COVERAGE
        int m = (n & 1) == 1 ? (n >> 1) + 2 : (n >> 1) + 1;
76
        int offset = vspace.alloc(m);
77
        byte[] va = vspace.getArray();
78 3 1. packValues : changed conditional boundary → NO_COVERAGE
2. packValues : Changed increment from 1 to -1 → NO_COVERAGE
3. packValues : negated conditional → NO_COVERAGE
        for (i = 0; i < n; i++) {
79 1 1. packValues : Replaced Shift Right with Shift Left → NO_COVERAGE
            int j = i >> 1;
80 3 1. packValues : Replaced integer subtraction with addition → NO_COVERAGE
2. packValues : Replaced integer addition with subtraction → NO_COVERAGE
3. packValues : Replaced bitwise AND with OR → NO_COVERAGE
            byte v = (byte)((values.charAt(i) - '0' + 1) & 0x0f);
81 2 1. packValues : Replaced bitwise AND with OR → NO_COVERAGE
2. packValues : negated conditional → NO_COVERAGE
            if ((i & 1) == 1) {
82 3 1. packValues : Replaced integer addition with subtraction → NO_COVERAGE
2. packValues : Replaced integer addition with subtraction → NO_COVERAGE
3. packValues : Replaced bitwise OR with AND → NO_COVERAGE
                va[j + offset] = (byte)(va[j + offset] | v);
83
            } else {
84 2 1. packValues : Replaced integer addition with subtraction → NO_COVERAGE
2. packValues : Replaced Shift Left with Shift Right → NO_COVERAGE
                va[j + offset] = (byte)(v << 4);    // big endian
85
            }
86
        }
87 2 1. packValues : Replaced integer subtraction with addition → NO_COVERAGE
2. packValues : Replaced integer addition with subtraction → NO_COVERAGE
        va[m - 1 + offset] = 0;    // terminator
88 1 1. packValues : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return offset;
89
    }
90
91
    protected String unpackValues(int k) {
92
        StringBuilder buf = new StringBuilder();
93 1 1. unpackValues : Changed increment from 1 to -1 → NO_COVERAGE
        byte v = vspace.get(k++);
94 1 1. unpackValues : negated conditional → NO_COVERAGE
        while (v != 0) {
95 3 1. unpackValues : Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE
2. unpackValues : Replaced integer subtraction with addition → NO_COVERAGE
3. unpackValues : Replaced integer addition with subtraction → NO_COVERAGE
            char c = (char)((v >>> 4) - 1 + '0');
96
            buf.append(c);
97 1 1. unpackValues : Replaced bitwise AND with OR → NO_COVERAGE
            c = (char)(v & 0x0f);
98 1 1. unpackValues : negated conditional → NO_COVERAGE
            if (c == 0) {
99
                break;
100
            }
101 2 1. unpackValues : Replaced integer subtraction with addition → NO_COVERAGE
2. unpackValues : Replaced integer addition with subtraction → NO_COVERAGE
            c = (char)(c - 1 + '0');
102
            buf.append(c);
103 1 1. unpackValues : Changed increment from 1 to -1 → NO_COVERAGE
            v = vspace.get(k++);
104
        }
105 1 1. unpackValues : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::unpackValues to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return buf.toString();
106
    }
107
108
    public void loadSimplePatterns(InputStream stream) {
109
        SimplePatternParser pp = new SimplePatternParser();
110
        ivalues = new TernaryTree();
111
112 1 1. loadSimplePatterns : removed call to com/lowagie/text/pdf/hyphenation/SimplePatternParser::parse → NO_COVERAGE
        pp.parse(stream, this);
113
114
        // patterns/values should be now in the tree
115
        // let's optimize a bit
116 1 1. loadSimplePatterns : removed call to com/lowagie/text/pdf/hyphenation/HyphenationTree::trimToSize → NO_COVERAGE
        trimToSize();
117 1 1. loadSimplePatterns : removed call to com/lowagie/text/pdf/hyphenation/ByteVector::trimToSize → NO_COVERAGE
        vspace.trimToSize();
118 1 1. loadSimplePatterns : removed call to com/lowagie/text/pdf/hyphenation/TernaryTree::trimToSize → NO_COVERAGE
        classmap.trimToSize();
119
120
        // get rid of the auxiliary map
121
        ivalues = null;
122
    }
123
124
125
    public String findPattern(String pat) {
126
        int k = super.find(pat);
127 2 1. findPattern : changed conditional boundary → NO_COVERAGE
2. findPattern : negated conditional → NO_COVERAGE
        if (k >= 0) {
128 1 1. findPattern : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::findPattern to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return unpackValues(k);
129
        }
130 1 1. findPattern : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::findPattern to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return "";
131
    }
132
133
    /**
134
     * String compare, returns 0 if equal or
135
     * t is a substring of s
136
     */
137
    protected int hstrcmp(char[] s, int si, char[] t, int ti) {
138 3 1. hstrcmp : Changed increment from 1 to -1 → NO_COVERAGE
2. hstrcmp : Changed increment from 1 to -1 → NO_COVERAGE
3. hstrcmp : negated conditional → NO_COVERAGE
        for (; s[si] == t[ti]; si++, ti++) {
139 1 1. hstrcmp : negated conditional → NO_COVERAGE
            if (s[si] == 0) {
140 1 1. hstrcmp : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
                return 0;
141
            }
142
        }
143 1 1. hstrcmp : negated conditional → NO_COVERAGE
        if (t[ti] == 0) {
144 1 1. hstrcmp : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return 0;
145
        }
146 2 1. hstrcmp : Replaced integer subtraction with addition → NO_COVERAGE
2. hstrcmp : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return s[si] - t[ti];
147
    }
148
149
    protected byte[] getValues(int k) {
150
        StringBuilder buf = new StringBuilder();
151 1 1. getValues : Changed increment from 1 to -1 → NO_COVERAGE
        byte v = vspace.get(k++);
152 1 1. getValues : negated conditional → NO_COVERAGE
        while (v != 0) {
153 2 1. getValues : Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE
2. getValues : Replaced integer subtraction with addition → NO_COVERAGE
            char c = (char)((v >>> 4) - 1);
154
            buf.append(c);
155 1 1. getValues : Replaced bitwise AND with OR → NO_COVERAGE
            c = (char)(v & 0x0f);
156 1 1. getValues : negated conditional → NO_COVERAGE
            if (c == 0) {
157
                break;
158
            }
159 1 1. getValues : Replaced integer subtraction with addition → NO_COVERAGE
            c = (char)(c - 1);
160
            buf.append(c);
161 1 1. getValues : Changed increment from 1 to -1 → NO_COVERAGE
            v = vspace.get(k++);
162
        }
163
        byte[] res = new byte[buf.length()];
164 2 1. getValues : changed conditional boundary → NO_COVERAGE
2. getValues : negated conditional → NO_COVERAGE
        for (int i = 0; i < res.length; i++) {
165
            res[i] = (byte)buf.charAt(i);
166
        }
167 1 1. getValues : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::getValues to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return res;
168
    }
169
170
    /**
171
     * <p>Search for all possible partial matches of word starting
172
     * at index an update interletter values. In other words, it
173
     * does something like:</p>
174
     * <code>
175
     * for(i=0; i<patterns.length; i++) {
176
     * if ( word.substring(index).startsWidth(patterns[i]) )
177
     * update_interletter_values(patterns[i]);
178
     * }
179
     * </code>
180
     * <p>But it is done in an efficient way since the patterns are
181
     * stored in a ternary tree. In fact, this is the whole purpose
182
     * of having the tree: doing this search without having to test
183
     * every single pattern. The number of patterns for languages
184
     * such as English range from 4000 to 10000. Thus, doing thousands
185
     * of string comparisons for each word to hyphenate would be
186
     * really slow without the tree. The tradeoff is memory, but
187
     * using a ternary tree instead of a trie, almost halves the
188
     * the memory used by Lout or TeX. It's also faster than using
189
     * a hash table</p>
190
     * @param word null terminated word to match
191
     * @param index start index from word
192
     * @param il interletter values array to update
193
     */
194
    protected void searchPatterns(char[] word, int index, byte[] il) {
195
        byte[] values;
196
        int i = index;
197
        char p, q;
198
        char sp = word[i];
199
        p = root;
200
201 4 1. searchPatterns : changed conditional boundary → NO_COVERAGE
2. searchPatterns : changed conditional boundary → NO_COVERAGE
3. searchPatterns : negated conditional → NO_COVERAGE
4. searchPatterns : negated conditional → NO_COVERAGE
        while (p > 0 && p < sc.length) {
202 1 1. searchPatterns : negated conditional → NO_COVERAGE
            if (sc[p] == 0xFFFF) {
203 1 1. searchPatterns : negated conditional → NO_COVERAGE
                if (hstrcmp(word, i, kv.getArray(), lo[p]) == 0) {
204
                    values = getValues(eq[p]);    // data pointer is in eq[]
205
                    int j = index;
206
                    for (byte value : values) {
207 4 1. searchPatterns : changed conditional boundary → NO_COVERAGE
2. searchPatterns : changed conditional boundary → NO_COVERAGE
3. searchPatterns : negated conditional → NO_COVERAGE
4. searchPatterns : negated conditional → NO_COVERAGE
                        if (j < il.length && value > il[j]) {
208
                            il[j] = value;
209
                        }
210 1 1. searchPatterns : Changed increment from 1 to -1 → NO_COVERAGE
                        j++;
211
                    }
212
                }
213
                return;
214
            }
215 1 1. searchPatterns : Replaced integer subtraction with addition → NO_COVERAGE
            int d = sp - sc[p];
216 1 1. searchPatterns : negated conditional → NO_COVERAGE
            if (d == 0) {
217 1 1. searchPatterns : negated conditional → NO_COVERAGE
                if (sp == 0) {
218
                    break;
219
                }
220 1 1. searchPatterns : Changed increment from 1 to -1 → NO_COVERAGE
                sp = word[++i];
221
                p = eq[p];
222
                q = p;
223
224
                // look for a pattern ending at this position by searching for
225
                // the null char ( splitchar == 0 )
226 4 1. searchPatterns : changed conditional boundary → NO_COVERAGE
2. searchPatterns : changed conditional boundary → NO_COVERAGE
3. searchPatterns : negated conditional → NO_COVERAGE
4. searchPatterns : negated conditional → NO_COVERAGE
                while (q > 0 && q < sc.length) {
227 1 1. searchPatterns : negated conditional → NO_COVERAGE
                    if (sc[q] == 0xFFFF) {        // stop at compressed branch
228
                        break;
229
                    }
230 1 1. searchPatterns : negated conditional → NO_COVERAGE
                    if (sc[q] == 0) {
231
                        values = getValues(eq[q]);
232
                        int j = index;
233
                        for (byte value : values) {
234 4 1. searchPatterns : changed conditional boundary → NO_COVERAGE
2. searchPatterns : changed conditional boundary → NO_COVERAGE
3. searchPatterns : negated conditional → NO_COVERAGE
4. searchPatterns : negated conditional → NO_COVERAGE
                            if (j < il.length && value > il[j]) {
235
                                il[j] = value;
236
                            }
237 1 1. searchPatterns : Changed increment from 1 to -1 → NO_COVERAGE
                            j++;
238
                        }
239
                        break;
240
                    } else {
241
                        q = lo[q];
242
243
                        /**
244
                         * actually the code should be:
245
                         * q = sc[q] < 0 ? hi[q] : lo[q];
246
                         * but java chars are unsigned
247
                         */
248
                    }
249
                }
250
            } else {
251 2 1. searchPatterns : changed conditional boundary → NO_COVERAGE
2. searchPatterns : negated conditional → NO_COVERAGE
                p = d < 0 ? lo[p] : hi[p];
252
            }
253
        }
254
    }
255
256
    /**
257
     * Hyphenate word and return a Hyphenation object.
258
     * @param word the word to be hyphenated
259
     * @param remainCharCount Minimum number of characters allowed
260
     * before the hyphenation point.
261
     * @param pushCharCount Minimum number of characters allowed after
262
     * the hyphenation point.
263
     * @return a {@link Hyphenation Hyphenation} object representing
264
     * the hyphenated word or null if word is not hyphenated.
265
     */
266
    public Hyphenation hyphenate(String word, int remainCharCount,
267
                                 int pushCharCount) {
268
        char[] w = word.toCharArray();
269 1 1. hyphenate : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return hyphenate(w, 0, w.length, remainCharCount, pushCharCount);
270
    }
271
272
    /**
273
     * w = "****nnllllllnnn*****",
274
     * where n is a non-letter, l is a letter,
275
     * all n may be absent, the first n is at offset,
276
     * the first l is at offset + iIgnoreAtBeginning;
277
     * word = ".llllll.'\0'***",
278
     * where all l in w are copied into word.
279
     * In the first part of the routine len = w.length,
280
     * in the second part of the routine len = word.length.
281
     * Three indices are used:
282
     * index(w), the index in w,
283
     * index(word), the index in word,
284
     * letterindex(word), the index in the letter part of word.
285
     * The following relations exist:
286
     * index(w) = offset + i - 1
287
     * index(word) = i - iIgnoreAtBeginning
288
     * letterindex(word) = index(word) - 1
289
     * (see first loop).
290
     * It follows that:
291
     * index(w) - index(word) = offset - 1 + iIgnoreAtBeginning
292
     * index(w) = letterindex(word) + offset + iIgnoreAtBeginning
293
     */
294
295
    /**
296
     * Hyphenate word and return an array of hyphenation points.
297
     * @param w char array that contains the word
298
     * @param offset Offset to first character in word
299
     * @param len Length of word
300
     * @param remainCharCount Minimum number of characters allowed
301
     * before the hyphenation point.
302
     * @param pushCharCount Minimum number of characters allowed after
303
     * the hyphenation point.
304
     * @return a {@link Hyphenation Hyphenation} object representing
305
     * the hyphenated word or null if word is not hyphenated.
306
     */
307
    public Hyphenation hyphenate(char[] w, int offset, int len,
308
                                 int remainCharCount, int pushCharCount) {
309
        int i;
310 1 1. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
        char[] word = new char[len + 3];
311
312
        // normalize word
313
        char[] c = new char[2];
314
        int iIgnoreAtBeginning = 0;
315
        int iLength = len;
316
        boolean bEndOfLetters = false;
317 3 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : Changed increment from 1 to -1 → NO_COVERAGE
3. hyphenate : negated conditional → NO_COVERAGE
        for (i = 1; i <= len; i++) {
318 2 1. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
2. hyphenate : Replaced integer subtraction with addition → NO_COVERAGE
            c[0] = w[offset + i - 1];
319
            int nc = classmap.find(c, 0);
320 2 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : negated conditional → NO_COVERAGE
            if (nc < 0) {    // found a non-letter character ...
321 2 1. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
2. hyphenate : negated conditional → NO_COVERAGE
                if (i == (1 + iIgnoreAtBeginning)) {
322
                    // ... before any letter character
323 1 1. hyphenate : Changed increment from 1 to -1 → NO_COVERAGE
                    iIgnoreAtBeginning ++;
324
                } else {
325
                    // ... after a letter character
326
                    bEndOfLetters = true;
327
                }
328 1 1. hyphenate : Changed increment from -1 to 1 → NO_COVERAGE
                iLength --;
329
            } else {
330 1 1. hyphenate : negated conditional → NO_COVERAGE
                if (!bEndOfLetters) {
331 1 1. hyphenate : Replaced integer subtraction with addition → NO_COVERAGE
                    word[i - iIgnoreAtBeginning] = (char)nc;
332
                } else {
333 1 1. hyphenate : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
                    return null;
334
                }
335
            }
336
        }
337
        len = iLength;
338 3 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
3. hyphenate : negated conditional → NO_COVERAGE
        if (len < (remainCharCount + pushCharCount)) {
339
            // word is too short to be hyphenated
340 1 1. hyphenate : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return null;
341
        }
342 1 1. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
        int[] result = new int[len + 1];
343
        int k = 0;
344
345
        // check exception list first
346
        String sw = new String(word, 1, len);
347 1 1. hyphenate : negated conditional → NO_COVERAGE
        if (stoplist.containsKey(sw)) {
348
            // assume only simple hyphens (Hyphen.pre="-", Hyphen.post = Hyphen.no = null)
349
            ArrayList hw = (ArrayList)stoplist.get(sw);
350
            int j = 0;
351 3 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : Changed increment from 1 to -1 → NO_COVERAGE
3. hyphenate : negated conditional → NO_COVERAGE
            for (i = 0; i < hw.size(); i++) {
352
                Object o = hw.get(i);
353
                // j = index(sw) = letterindex(word)?
354
                // result[k] = corresponding index(w)
355 1 1. hyphenate : negated conditional → NO_COVERAGE
                if (o instanceof String) {
356 1 1. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
                    j += ((String)o).length();
357 5 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : changed conditional boundary → NO_COVERAGE
3. hyphenate : Replaced integer subtraction with addition → NO_COVERAGE
4. hyphenate : negated conditional → NO_COVERAGE
5. hyphenate : negated conditional → NO_COVERAGE
                    if (j >= remainCharCount && j < (len - pushCharCount)) {
358 2 1. hyphenate : Changed increment from 1 to -1 → NO_COVERAGE
2. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
                        result[k++] = j + iIgnoreAtBeginning;
359
                    }
360
                }
361
            }
362
        } else {
363
            // use algorithm to get hyphenation points
364
            word[0] = '.';                    // word start marker
365 1 1. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
            word[len + 1] = '.';              // word end marker
366 1 1. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
            word[len + 2] = 0;                // null terminated
367 1 1. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
            byte[] il = new byte[len + 3];    // initialized to zero
368 4 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : Changed increment from 1 to -1 → NO_COVERAGE
3. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
4. hyphenate : negated conditional → NO_COVERAGE
            for (i = 0; i < len + 1; i++) {
369 1 1. hyphenate : removed call to com/lowagie/text/pdf/hyphenation/HyphenationTree::searchPatterns → NO_COVERAGE
                searchPatterns(word, i, il);
370
            }
371
372
            // hyphenation points are located where interletter value is odd
373
            // i is letterindex(word),
374
            // i + 1 is index(word),
375
            // result[k] = corresponding index(w)
376 3 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : Changed increment from 1 to -1 → NO_COVERAGE
3. hyphenate : negated conditional → NO_COVERAGE
            for (i = 0; i < len; i++) {
377 8 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : changed conditional boundary → NO_COVERAGE
3. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
4. hyphenate : Replaced bitwise AND with OR → NO_COVERAGE
5. hyphenate : Replaced integer subtraction with addition → NO_COVERAGE
6. hyphenate : negated conditional → NO_COVERAGE
7. hyphenate : negated conditional → NO_COVERAGE
8. hyphenate : negated conditional → NO_COVERAGE
                if (((il[i + 1] & 1) == 1) && i >= remainCharCount
378
                        && i <= (len - pushCharCount)) {
379 2 1. hyphenate : Changed increment from 1 to -1 → NO_COVERAGE
2. hyphenate : Replaced integer addition with subtraction → NO_COVERAGE
                    result[k++] = i + iIgnoreAtBeginning;
380
                }
381
            }
382
        }
383
384
385 2 1. hyphenate : changed conditional boundary → NO_COVERAGE
2. hyphenate : negated conditional → NO_COVERAGE
        if (k > 0) {
386
            // trim result array
387
            int[] res = new int[k];
388 1 1. hyphenate : removed call to java/lang/System::arraycopy → NO_COVERAGE
            System.arraycopy(result, 0, res, 0, k);
389 1 1. hyphenate : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return new Hyphenation(new String(w, offset, len), res);
390
        } else {
391 1 1. hyphenate : mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return null;
392
        }
393
    }
394
395
    /**
396
     * Add a character class to the tree. It is used by
397
     * {@link SimplePatternParser SimplePatternParser} as callback to
398
     * add character classes. Character classes define the
399
     * valid word characters for hyphenation. If a word contains
400
     * a character not defined in any of the classes, it is not hyphenated.
401
     * It also defines a way to normalize the characters in order
402
     * to compare them with the stored patterns. Usually pattern
403
     * files use only lower case characters, in this case a class
404
     * for letter 'a', for example, should be defined as "aA", the first
405
     * character being the normalization char.
406
     */
407
    public void addClass(String chargroup) {
408 2 1. addClass : changed conditional boundary → NO_COVERAGE
2. addClass : negated conditional → NO_COVERAGE
        if (chargroup.length() > 0) {
409
            char equivChar = chargroup.charAt(0);
410
            char[] key = new char[2];
411
            key[1] = 0;
412 2 1. addClass : changed conditional boundary → NO_COVERAGE
2. addClass : negated conditional → NO_COVERAGE
            for (int i = 0; i < chargroup.length(); i++) {
413
                key[0] = chargroup.charAt(i);
414 1 1. addClass : removed call to com/lowagie/text/pdf/hyphenation/TernaryTree::insert → NO_COVERAGE
                classmap.insert(key, 0, equivChar);
415
            }
416
        }
417
    }
418
419
    /**
420
     * Add an exception to the tree. It is used by
421
     * {@link SimplePatternParser SimplePatternParser} class as callback to
422
     * store the hyphenation exceptions.
423
     * @param word normalized word
424
     * @param hyphenatedword a vector of alternating strings and
425
     * {@link Hyphen hyphen} objects.
426
     */
427
    public void addException(String word, ArrayList hyphenatedword) {
428
        stoplist.put(word, hyphenatedword);
429
    }
430
431
    /**
432
     * Add a pattern to the tree. Mainly, to be used by
433
     * {@link SimplePatternParser SimplePatternParser} class as callback to
434
     * add a pattern to the tree.
435
     * @param pattern the hyphenation pattern
436
     * @param ivalue interletter weight values indicating the
437
     * desirability and priority of hyphenating at a given point
438
     * within the pattern. It should contain only digit characters.
439
     * (i.e. '0' to '9').
440
     */
441
    public void addPattern(String pattern, String ivalue) {
442
        int k = ivalues.find(ivalue);
443 2 1. addPattern : changed conditional boundary → NO_COVERAGE
2. addPattern : negated conditional → NO_COVERAGE
        if (k <= 0) {
444
            k = packValues(ivalue);
445 1 1. addPattern : removed call to com/lowagie/text/pdf/hyphenation/TernaryTree::insert → NO_COVERAGE
            ivalues.insert(ivalue, (char)k);
446
        }
447 1 1. addPattern : removed call to com/lowagie/text/pdf/hyphenation/HyphenationTree::insert → NO_COVERAGE
        insert(pattern, (char)k);
448
    }
449
450
    public void printStats() {
451 1 1. printStats : removed call to java/io/PrintStream::println → NO_COVERAGE
        System.out.println("Value space size = "
452
                           + vspace.length());
453 1 1. printStats : removed call to com/lowagie/text/pdf/hyphenation/TernaryTree::printStats → NO_COVERAGE
        super.printStats();
454
    }
455
}

Mutations

75

1.1
Location : packValues
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

2.2
Location : packValues
Killed by : none
Replaced Shift Right with Shift Left → NO_COVERAGE

3.3
Location : packValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

4.4
Location : packValues
Killed by : none
Replaced Shift Right with Shift Left → NO_COVERAGE

5.5
Location : packValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

6.6
Location : packValues
Killed by : none
negated conditional → NO_COVERAGE

78

1.1
Location : packValues
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : packValues
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : packValues
Killed by : none
negated conditional → NO_COVERAGE

79

1.1
Location : packValues
Killed by : none
Replaced Shift Right with Shift Left → NO_COVERAGE

80

1.1
Location : packValues
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : packValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

3.3
Location : packValues
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

81

1.1
Location : packValues
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

2.2
Location : packValues
Killed by : none
negated conditional → NO_COVERAGE

82

1.1
Location : packValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : packValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

3.3
Location : packValues
Killed by : none
Replaced bitwise OR with AND → NO_COVERAGE

84

1.1
Location : packValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : packValues
Killed by : none
Replaced Shift Left with Shift Right → NO_COVERAGE

87

1.1
Location : packValues
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : packValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

88

1.1
Location : packValues
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

93

1.1
Location : unpackValues
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

94

1.1
Location : unpackValues
Killed by : none
negated conditional → NO_COVERAGE

95

1.1
Location : unpackValues
Killed by : none
Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE

2.2
Location : unpackValues
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

3.3
Location : unpackValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

97

1.1
Location : unpackValues
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

98

1.1
Location : unpackValues
Killed by : none
negated conditional → NO_COVERAGE

101

1.1
Location : unpackValues
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : unpackValues
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

103

1.1
Location : unpackValues
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

105

1.1
Location : unpackValues
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::unpackValues to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

112

1.1
Location : loadSimplePatterns
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/SimplePatternParser::parse → NO_COVERAGE

116

1.1
Location : loadSimplePatterns
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/HyphenationTree::trimToSize → NO_COVERAGE

117

1.1
Location : loadSimplePatterns
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/ByteVector::trimToSize → NO_COVERAGE

118

1.1
Location : loadSimplePatterns
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/TernaryTree::trimToSize → NO_COVERAGE

127

1.1
Location : findPattern
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : findPattern
Killed by : none
negated conditional → NO_COVERAGE

128

1.1
Location : findPattern
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::findPattern to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

130

1.1
Location : findPattern
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::findPattern to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

138

1.1
Location : hstrcmp
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

2.2
Location : hstrcmp
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : hstrcmp
Killed by : none
negated conditional → NO_COVERAGE

139

1.1
Location : hstrcmp
Killed by : none
negated conditional → NO_COVERAGE

140

1.1
Location : hstrcmp
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

143

1.1
Location : hstrcmp
Killed by : none
negated conditional → NO_COVERAGE

144

1.1
Location : hstrcmp
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

146

1.1
Location : hstrcmp
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : hstrcmp
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

151

1.1
Location : getValues
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

152

1.1
Location : getValues
Killed by : none
negated conditional → NO_COVERAGE

153

1.1
Location : getValues
Killed by : none
Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE

2.2
Location : getValues
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

155

1.1
Location : getValues
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

156

1.1
Location : getValues
Killed by : none
negated conditional → NO_COVERAGE

159

1.1
Location : getValues
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

161

1.1
Location : getValues
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

164

1.1
Location : getValues
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : getValues
Killed by : none
negated conditional → NO_COVERAGE

167

1.1
Location : getValues
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::getValues to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

201

1.1
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

202

1.1
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

203

1.1
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

207

1.1
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

210

1.1
Location : searchPatterns
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

215

1.1
Location : searchPatterns
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

216

1.1
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

217

1.1
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

220

1.1
Location : searchPatterns
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

226

1.1
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

227

1.1
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

230

1.1
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

234

1.1
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

237

1.1
Location : searchPatterns
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

251

1.1
Location : searchPatterns
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : searchPatterns
Killed by : none
negated conditional → NO_COVERAGE

269

1.1
Location : hyphenate
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

310

1.1
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

317

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

318

1.1
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

320

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

321

1.1
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

323

1.1
Location : hyphenate
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

328

1.1
Location : hyphenate
Killed by : none
Changed increment from -1 to 1 → NO_COVERAGE

330

1.1
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

331

1.1
Location : hyphenate
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

333

1.1
Location : hyphenate
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

338

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

3.3
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

340

1.1
Location : hyphenate
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

342

1.1
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

347

1.1
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

351

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

355

1.1
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

356

1.1
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

357

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : hyphenate
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

4.4
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

5.5
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

358

1.1
Location : hyphenate
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

365

1.1
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

366

1.1
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

367

1.1
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

368

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

4.4
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

369

1.1
Location : hyphenate
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/HyphenationTree::searchPatterns → NO_COVERAGE

376

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

377

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

4.4
Location : hyphenate
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

5.5
Location : hyphenate
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

6.6
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

7.7
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

8.8
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

379

1.1
Location : hyphenate
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

385

1.1
Location : hyphenate
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : hyphenate
Killed by : none
negated conditional → NO_COVERAGE

388

1.1
Location : hyphenate
Killed by : none
removed call to java/lang/System::arraycopy → NO_COVERAGE

389

1.1
Location : hyphenate
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

391

1.1
Location : hyphenate
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/hyphenation/HyphenationTree::hyphenate to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

408

1.1
Location : addClass
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : addClass
Killed by : none
negated conditional → NO_COVERAGE

412

1.1
Location : addClass
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : addClass
Killed by : none
negated conditional → NO_COVERAGE

414

1.1
Location : addClass
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/TernaryTree::insert → NO_COVERAGE

443

1.1
Location : addPattern
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : addPattern
Killed by : none
negated conditional → NO_COVERAGE

445

1.1
Location : addPattern
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/TernaryTree::insert → NO_COVERAGE

447

1.1
Location : addPattern
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/HyphenationTree::insert → NO_COVERAGE

451

1.1
Location : printStats
Killed by : none
removed call to java/io/PrintStream::println → NO_COVERAGE

453

1.1
Location : printStats
Killed by : none
removed call to com/lowagie/text/pdf/hyphenation/TernaryTree::printStats → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.4.2