CMapParser.java

1
/**
2
 * Copyright (c) 2005-2006, www.fontbox.org
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of fontbox; nor the names of its
14
 *    contributors may be used to endorse or promote products derived from this
15
 *    software without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
 * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
21
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 *
28
 * http://www.fontbox.org
29
 *
30
 */
31
package com.lowagie.text.pdf.fonts.cmaps;
32
33
import java.io.FileInputStream;
34
import java.io.InputStream;
35
import java.io.IOException;
36
import java.io.PushbackInputStream;
37
import com.lowagie.text.error_messages.MessageLocalization;
38
39
import java.nio.charset.StandardCharsets;
40
import java.util.ArrayList;
41
import java.util.HashMap;
42
import java.util.List;
43
import java.util.Map;
44
45
/**
46
 * This will parser a CMap stream.
47
 *
48
 * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
49
 * @version $Revision: 4065 $
50
 * @since    2.1.4
51
 */
52
public class CMapParser
53
{
54
    private static final String BEGIN_CODESPACE_RANGE = "begincodespacerange";
55
    private static final String BEGIN_BASE_FONT_CHAR = "beginbfchar";
56
    private static final String BEGIN_BASE_FONT_RANGE = "beginbfrange";
57
    
58
    private static final String MARK_END_OF_DICTIONARY = ">>";
59
    private static final String MARK_END_OF_ARRAY = "]";
60
    
61
    private byte[] tokenParserByteBuffer = new byte[512];
62
63
    /**
64
     * Creates a new instance of CMapParser.
65
     */
66
    public CMapParser()
67
    {
68
    }
69
70
    /**
71
     * This will parse the stream and create a cmap object.
72
     *
73
     * @param input The CMAP stream to parse.
74
     * @return The parsed stream as a java object.
75
     *
76
     * @throws IOException If there is an error parsing the stream.
77
     */
78
    public CMap parse( InputStream input ) throws IOException
79
    {
80
        PushbackInputStream cmapStream = new PushbackInputStream( input );
81
        CMap result = new CMap();
82
        Object previousToken = null;
83
        Object token = null;
84 1 1. parse : negated conditional → NO_COVERAGE
        while( (token = parseNextToken( cmapStream )) != null )
85
        {
86 1 1. parse : negated conditional → NO_COVERAGE
            if( token instanceof Operator )
87
            {
88
                Operator op = (Operator)token;
89
                switch (op.op) {
90
                    case BEGIN_CODESPACE_RANGE: {
91
                        Number cosCount = (Number) previousToken;
92 2 1. parse : changed conditional boundary → NO_COVERAGE
2. parse : negated conditional → NO_COVERAGE
                        for (int j = 0; j < cosCount.intValue(); j++) {
93
                            byte[] startRange = (byte[]) parseNextToken(cmapStream);
94
                            byte[] endRange = (byte[]) parseNextToken(cmapStream);
95
                            CodespaceRange range = new CodespaceRange();
96 1 1. parse : removed call to com/lowagie/text/pdf/fonts/cmaps/CodespaceRange::setStart → NO_COVERAGE
                            range.setStart(startRange);
97 1 1. parse : removed call to com/lowagie/text/pdf/fonts/cmaps/CodespaceRange::setEnd → NO_COVERAGE
                            range.setEnd(endRange);
98 1 1. parse : removed call to com/lowagie/text/pdf/fonts/cmaps/CMap::addCodespaceRange → NO_COVERAGE
                            result.addCodespaceRange(range);
99
                        }
100
                        break;
101
                    }
102
                    case BEGIN_BASE_FONT_CHAR: {
103
                        Number cosCount = (Number) previousToken;
104 2 1. parse : changed conditional boundary → NO_COVERAGE
2. parse : negated conditional → NO_COVERAGE
                        for (int j = 0; j < cosCount.intValue(); j++) {
105
                            byte[] inputCode = (byte[]) parseNextToken(cmapStream);
106
                            Object nextToken = parseNextToken(cmapStream);
107 1 1. parse : negated conditional → NO_COVERAGE
                            if (nextToken instanceof byte[]) {
108
                                byte[] bytes = (byte[]) nextToken;
109
                                String value = createStringFromBytes(bytes);
110 1 1. parse : removed call to com/lowagie/text/pdf/fonts/cmaps/CMap::addMapping → NO_COVERAGE
                                result.addMapping(inputCode, value);
111 1 1. parse : negated conditional → NO_COVERAGE
                            } else if (nextToken instanceof LiteralName) {
112 1 1. parse : removed call to com/lowagie/text/pdf/fonts/cmaps/CMap::addMapping → NO_COVERAGE
                                result.addMapping(inputCode, ((LiteralName) nextToken).name);
113
                            } else {
114
                                throw new IOException(MessageLocalization.getComposedMessage("error.parsing.cmap.beginbfchar.expected.cosstring.or.cosname.and.not.1", nextToken));
115
                            }
116
                        }
117
                        break;
118
                    }
119
                    case BEGIN_BASE_FONT_RANGE: {
120
                        Number cosCount = (Number) previousToken;
121
122 3 1. parse : changed conditional boundary → NO_COVERAGE
2. parse : Changed increment from 1 to -1 → NO_COVERAGE
3. parse : negated conditional → NO_COVERAGE
                        for (int j = 0; j < cosCount.intValue(); j++) {
123
                            byte[] startCode = (byte[]) parseNextToken(cmapStream);
124
                            byte[] endCode = (byte[]) parseNextToken(cmapStream);
125
                            Object nextToken = parseNextToken(cmapStream);
126
                            List array = null;
127
                            byte[] tokenBytes = null;
128 1 1. parse : negated conditional → NO_COVERAGE
                            if (nextToken instanceof List) {
129
                                array = (List) nextToken;
130
                                tokenBytes = (byte[]) array.get(0);
131
                            } else {
132
                                tokenBytes = (byte[]) nextToken;
133
                            }
134
135
                            String value = null;
136
137
                            int arrayIndex = 0;
138
                            boolean done = false;
139 1 1. parse : negated conditional → NO_COVERAGE
                            while (!done) {
140 2 1. parse : changed conditional boundary → NO_COVERAGE
2. parse : negated conditional → NO_COVERAGE
                                if (compare(startCode, endCode) >= 0) {
141
                                    done = true;
142
                                }
143
                                value = createStringFromBytes(tokenBytes);
144 1 1. parse : removed call to com/lowagie/text/pdf/fonts/cmaps/CMap::addMapping → NO_COVERAGE
                                result.addMapping(startCode, value);
145 1 1. parse : removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::increment → NO_COVERAGE
                                increment(startCode);
146
147 1 1. parse : negated conditional → NO_COVERAGE
                                if (array == null) {
148 1 1. parse : removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::increment → NO_COVERAGE
                                    increment(tokenBytes);
149
                                } else {
150 1 1. parse : Changed increment from 1 to -1 → NO_COVERAGE
                                    arrayIndex++;
151 2 1. parse : changed conditional boundary → NO_COVERAGE
2. parse : negated conditional → NO_COVERAGE
                                    if (arrayIndex < array.size()) {
152
                                        tokenBytes = (byte[]) array.get(arrayIndex);
153
                                    }
154
                                }
155
                            }
156
                        }
157
                        break;
158
                    }
159
                }
160
            }
161
            previousToken = token;
162
        }
163 1 1. parse : mutated return of Object value for com/lowagie/text/pdf/fonts/cmaps/CMapParser::parse to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return result;
164
    }
165
    
166
    private Object parseNextToken( PushbackInputStream is ) throws IOException
167
    {
168
        Object retval = null;
169
        int nextByte = is.read();
170
        //skip whitespace
171 4 1. parseNextToken : negated conditional → NO_COVERAGE
2. parseNextToken : negated conditional → NO_COVERAGE
3. parseNextToken : negated conditional → NO_COVERAGE
4. parseNextToken : negated conditional → NO_COVERAGE
        while( nextByte == 0x09 || nextByte == 0x20 || nextByte == 0x0D || nextByte == 0x0A )
172
        {
173
            nextByte = is.read();
174
        }
175
        switch( nextByte )
176
        {
177
            case '%':
178
            {
179
                //header operations, for now return the entire line 
180
                //may need to smarter in the future
181
                StringBuffer buffer = new StringBuffer();
182
                buffer.append( (char)nextByte );
183 1 1. parseNextToken : removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::readUntilEndOfLine → NO_COVERAGE
                readUntilEndOfLine( is, buffer );
184
                retval = buffer.toString();
185
                break;
186
            }
187
            case '(':
188
            {
189
                StringBuilder buffer = new StringBuilder();
190
                int stringByte = is.read();
191
                
192 2 1. parseNextToken : negated conditional → NO_COVERAGE
2. parseNextToken : negated conditional → NO_COVERAGE
                while( stringByte != -1 && stringByte != ')' )
193
                {
194
                    buffer.append( (char)stringByte );
195
                    stringByte = is.read();
196
                }
197
                retval = buffer.toString();
198
                break;
199
            }
200
            case '>':
201
            {
202
                int secondCloseBrace = is.read();
203 1 1. parseNextToken : negated conditional → NO_COVERAGE
                if( secondCloseBrace == '>' )
204
                {
205
                    retval = MARK_END_OF_DICTIONARY;
206
                }
207
                else
208
                {
209
                    throw new IOException(MessageLocalization.getComposedMessage("error.expected.the.end.of.a.dictionary"));
210
                }
211
                break;
212
            }
213
            case ']':
214
            {
215
                retval = MARK_END_OF_ARRAY;
216
                break;
217
            }
218
            case '[':
219
            {
220
                List list = new ArrayList();
221
                
222
                Object nextToken = parseNextToken( is ); 
223 1 1. parseNextToken : negated conditional → NO_COVERAGE
                while( nextToken != MARK_END_OF_ARRAY )
224
                {
225
                    list.add( nextToken );
226
                    nextToken = parseNextToken( is );
227
                }
228
                retval = list;
229
                break;
230
            }
231
            case '<':
232
            {
233
                int theNextByte = is.read();
234 1 1. parseNextToken : negated conditional → NO_COVERAGE
                if( theNextByte == '<' )
235
                {
236
                    Map result = new HashMap();
237
                    //we are reading a dictionary
238
                    Object key = parseNextToken( is ); 
239 2 1. parseNextToken : negated conditional → NO_COVERAGE
2. parseNextToken : negated conditional → NO_COVERAGE
                    while( key instanceof LiteralName && key != MARK_END_OF_DICTIONARY )
240
                    {
241
                        Object value = parseNextToken( is );
242
                        result.put( ((LiteralName)key).name, value );
243
                        key = parseNextToken( is );
244
                    }
245
                    retval = result;
246
                }
247
                else
248
                {
249
                    //won't read more than 512 bytes
250
                    
251
                    int multiplyer = 16;
252
                    int bufferIndex = -1;
253 2 1. parseNextToken : negated conditional → NO_COVERAGE
2. parseNextToken : negated conditional → NO_COVERAGE
                    while( theNextByte != -1 && theNextByte != '>' )
254
                    {
255
                        int intValue = 0;
256 5 1. parseNextToken : negated conditional → NO_COVERAGE
2. parseNextToken : negated conditional → NO_COVERAGE
3. parseNextToken : negated conditional → NO_COVERAGE
4. parseNextToken : negated conditional → NO_COVERAGE
5. parseNextToken : negated conditional → NO_COVERAGE
                        if (theNextByte == ' ' || theNextByte == '\t' || theNextByte == '\n' || theNextByte == '\r'
257
                            || theNextByte == '\f')
258
                        {
259
                            theNextByte = is.read();
260
                            continue;
261
                        }
262 4 1. parseNextToken : changed conditional boundary → NO_COVERAGE
2. parseNextToken : changed conditional boundary → NO_COVERAGE
3. parseNextToken : negated conditional → NO_COVERAGE
4. parseNextToken : negated conditional → NO_COVERAGE
                        else if (theNextByte >= '0' && theNextByte <= '9')
263
                        {
264 1 1. parseNextToken : Replaced integer subtraction with addition → NO_COVERAGE
                            intValue = theNextByte - '0';
265
                        }
266 4 1. parseNextToken : changed conditional boundary → NO_COVERAGE
2. parseNextToken : changed conditional boundary → NO_COVERAGE
3. parseNextToken : negated conditional → NO_COVERAGE
4. parseNextToken : negated conditional → NO_COVERAGE
                        else if( theNextByte >= 'A' && theNextByte <= 'F' )
267
                        {
268 2 1. parseNextToken : Replaced integer addition with subtraction → NO_COVERAGE
2. parseNextToken : Replaced integer subtraction with addition → NO_COVERAGE
                            intValue = 10 + theNextByte - 'A';
269
                        }
270 4 1. parseNextToken : changed conditional boundary → NO_COVERAGE
2. parseNextToken : changed conditional boundary → NO_COVERAGE
3. parseNextToken : negated conditional → NO_COVERAGE
4. parseNextToken : negated conditional → NO_COVERAGE
                        else if( theNextByte >= 'a' && theNextByte <= 'f' )
271
                        {
272 2 1. parseNextToken : Replaced integer addition with subtraction → NO_COVERAGE
2. parseNextToken : Replaced integer subtraction with addition → NO_COVERAGE
                            intValue = 10 + theNextByte - 'a';
273
                        }
274
                        else
275
                        {
276
                            throw new IOException(MessageLocalization.getComposedMessage("error.expected.hex.character.and.not.char.thenextbyte.1", theNextByte));
277
                        }
278 1 1. parseNextToken : Replaced integer multiplication with division → NO_COVERAGE
                        intValue *= multiplyer;
279 1 1. parseNextToken : negated conditional → NO_COVERAGE
                        if( multiplyer == 16 )
280
                        {
281 1 1. parseNextToken : Changed increment from 1 to -1 → NO_COVERAGE
                            bufferIndex++;
282
                            tokenParserByteBuffer[bufferIndex] = 0;
283
                            multiplyer = 1;
284
                        }
285
                        else
286
                        {
287
                            multiplyer = 16;
288
                        }
289 1 1. parseNextToken : Replaced integer addition with subtraction → NO_COVERAGE
                        tokenParserByteBuffer[bufferIndex]+= intValue;
290
                        theNextByte = is.read();
291
                    }
292 1 1. parseNextToken : Replaced integer addition with subtraction → NO_COVERAGE
                    byte[] finalResult = new byte[bufferIndex+1];
293 2 1. parseNextToken : Replaced integer addition with subtraction → NO_COVERAGE
2. parseNextToken : removed call to java/lang/System::arraycopy → NO_COVERAGE
                    System.arraycopy(tokenParserByteBuffer,0,finalResult, 0, bufferIndex+1);
294
                    retval = finalResult;
295
                }
296
                break;
297
            }
298
            case '/':
299
            {
300
                StringBuilder buffer = new StringBuilder();
301
                int stringByte = is.read();
302
                
303 1 1. parseNextToken : negated conditional → NO_COVERAGE
                while( !isWhitespaceOrEOF( stringByte ) )
304
                {
305
                    buffer.append( (char)stringByte );
306
                    stringByte = is.read();
307
                }
308
                retval = new LiteralName( buffer.toString() );
309
                break;
310
            }
311
            case -1:
312
            {
313
                //EOF return null;
314
                break;
315
            }
316
            case '0':
317
            case '1':
318
            case '2':
319
            case '3':
320
            case '4':
321
            case '5':
322
            case '6':
323
            case '7':
324
            case '8':
325
            case '9':
326
            {
327
                StringBuilder buffer = new StringBuilder();
328
                buffer.append( (char)nextByte );
329
                nextByte = is.read();
330
                
331 1 1. parseNextToken : negated conditional → NO_COVERAGE
                while( !isWhitespaceOrEOF( nextByte ) &&
332 2 1. parseNextToken : negated conditional → NO_COVERAGE
2. parseNextToken : negated conditional → NO_COVERAGE
                        (Character.isDigit( (char)nextByte )||
333
                         nextByte == '.' ) )
334
                {
335
                    buffer.append( (char)nextByte );
336
                    nextByte = is.read();
337
                }
338 1 1. parseNextToken : removed call to java/io/PushbackInputStream::unread → NO_COVERAGE
                is.unread( nextByte );
339
                String value = buffer.toString();
340 2 1. parseNextToken : changed conditional boundary → NO_COVERAGE
2. parseNextToken : negated conditional → NO_COVERAGE
                if( value.indexOf( '.' ) >=0 )
341
                {
342
                    retval = new Double( value );
343
                }
344
                else
345
                {
346
                    retval = Integer.valueOf(buffer.toString());
347
                }
348
                break;
349
            }
350
            default:
351
            {
352
                StringBuilder buffer = new StringBuilder();
353
                buffer.append( (char)nextByte );
354
                nextByte = is.read();
355
                
356 1 1. parseNextToken : negated conditional → NO_COVERAGE
                while( !isWhitespaceOrEOF( nextByte ) )
357
                {
358
                    buffer.append( (char)nextByte );
359
                    nextByte = is.read();
360
                }
361
                retval = new Operator( buffer.toString() );                        
362
                
363
                break;
364
            }
365
        }
366 1 1. parseNextToken : mutated return of Object value for com/lowagie/text/pdf/fonts/cmaps/CMapParser::parseNextToken to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return retval;
367
    }
368
    
369
    private void readUntilEndOfLine( InputStream is, StringBuffer buf ) throws IOException
370
    {
371
        int nextByte = is.read();
372 3 1. readUntilEndOfLine : negated conditional → NO_COVERAGE
2. readUntilEndOfLine : negated conditional → NO_COVERAGE
3. readUntilEndOfLine : negated conditional → NO_COVERAGE
        while( nextByte != -1 && nextByte != 0x0D && nextByte != 0x0A )
373
        {
374
            buf.append( (char)nextByte );
375
            nextByte = is.read();
376
        }
377
    }
378
    
379
    private boolean isWhitespaceOrEOF( int aByte )
380
    {
381 5 1. isWhitespaceOrEOF : negated conditional → NO_COVERAGE
2. isWhitespaceOrEOF : negated conditional → NO_COVERAGE
3. isWhitespaceOrEOF : negated conditional → NO_COVERAGE
4. isWhitespaceOrEOF : negated conditional → NO_COVERAGE
5. isWhitespaceOrEOF : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return aByte == -1 || aByte == 0x20 || aByte == 0x0D || aByte == 0x0A; 
382
    }
383
    
384
385
    private void increment( byte[] data )
386
    {
387 2 1. increment : Replaced integer subtraction with addition → NO_COVERAGE
2. increment : removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::increment → NO_COVERAGE
        increment( data, data.length-1 );
388
    }
389
390
    private void increment( byte[] data, int position )
391
    {
392 5 1. increment : changed conditional boundary → NO_COVERAGE
2. increment : Replaced integer addition with subtraction → NO_COVERAGE
3. increment : Replaced integer modulus with multiplication → NO_COVERAGE
4. increment : negated conditional → NO_COVERAGE
5. increment : negated conditional → NO_COVERAGE
        if( position > 0 && (data[position]+256)%256 == 255 )
393
        {
394
            data[position]=0;
395 2 1. increment : Replaced integer subtraction with addition → NO_COVERAGE
2. increment : removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::increment → NO_COVERAGE
            increment( data, position-1);
396
        }
397
        else
398
        {
399 1 1. increment : Replaced integer addition with subtraction → NO_COVERAGE
            data[position] = (byte)(data[position]+1);
400
        }
401
    }
402
    
403
    private String createStringFromBytes( byte[] bytes ) throws IOException
404
    {
405
        String retval = null;
406 1 1. createStringFromBytes : negated conditional → NO_COVERAGE
        if( bytes.length == 1 )
407
        {
408
            retval = new String( bytes );
409
        }
410
        else
411
        {
412
            retval = new String( bytes, StandardCharsets.UTF_16BE);
413
        }
414 1 1. createStringFromBytes : mutated return of Object value for com/lowagie/text/pdf/fonts/cmaps/CMapParser::createStringFromBytes to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return retval;
415
    }
416
417
    private int compare( byte[] first, byte[] second )
418
    {
419
        int retval = 1;
420
        boolean done = false;
421 4 1. compare : changed conditional boundary → NO_COVERAGE
2. compare : Changed increment from 1 to -1 → NO_COVERAGE
3. compare : negated conditional → NO_COVERAGE
4. compare : negated conditional → NO_COVERAGE
        for( int i=0; i<first.length && !done; i++ )
422
        {
423 1 1. compare : negated conditional → NO_COVERAGE
            if( first[i] == second[i] )
424
            {
425
                //move to next position
426
            }
427 6 1. compare : changed conditional boundary → NO_COVERAGE
2. compare : Replaced integer addition with subtraction → NO_COVERAGE
3. compare : Replaced integer modulus with multiplication → NO_COVERAGE
4. compare : Replaced integer addition with subtraction → NO_COVERAGE
5. compare : Replaced integer modulus with multiplication → NO_COVERAGE
6. compare : negated conditional → NO_COVERAGE
            else if( ((first[i]+256)%256) < ((second[i]+256)%256) )
428
            {
429
                done = true;
430
                retval = -1;
431
            }
432
            else
433
            {
434
                done = true;
435
                retval = 1;
436
            }
437
        }
438 1 1. compare : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return retval;
439
    }
440
    
441
    /**
442
     * Internal class.
443
     */
444
    private class LiteralName
445
    {
446
        private String name;
447
        private LiteralName( String theName )
448
        {
449
            name = theName;
450
        }
451
    }
452
    
453
    /**
454
     * Internal class.
455
     */
456
    private class Operator
457
    {
458
        private String op;
459
        private Operator( String theOp )
460
        {
461
            op = theOp;
462
        }
463
    }
464
    
465
    /**
466
     * A simple class to test parsing of cmap files.
467
     * 
468
     * @param args Some command line arguments.
469
     * 
470
     * @throws Exception If there is an error parsing the file.
471
     */
472
    public static void main( String[] args ) throws Exception
473
    {
474 1 1. main : negated conditional → NO_COVERAGE
        if( args.length != 1 )
475
        {
476 1 1. main : removed call to java/io/PrintStream::println → NO_COVERAGE
            System.err.println( "usage: java org.pdfbox.cmapparser.CMapParser <CMAP File>" );
477 1 1. main : removed call to java/lang/System::exit → NO_COVERAGE
            System.exit( -1 );
478
        }
479
        CMapParser parser = new CMapParser(  );
480
        CMap result = parser.parse( new FileInputStream( args[0] ) );
481 1 1. main : removed call to java/io/PrintStream::println → NO_COVERAGE
        System.out.println( "Result:" + result );
482
    }
483
}

Mutations

84

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

86

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

92

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

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

96

1.1
Location : parse
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CodespaceRange::setStart → NO_COVERAGE

97

1.1
Location : parse
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CodespaceRange::setEnd → NO_COVERAGE

98

1.1
Location : parse
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMap::addCodespaceRange → NO_COVERAGE

104

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

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

107

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

110

1.1
Location : parse
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMap::addMapping → NO_COVERAGE

111

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

112

1.1
Location : parse
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMap::addMapping → NO_COVERAGE

122

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

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

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

128

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

139

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

140

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

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

144

1.1
Location : parse
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMap::addMapping → NO_COVERAGE

145

1.1
Location : parse
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::increment → NO_COVERAGE

147

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

148

1.1
Location : parse
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::increment → NO_COVERAGE

150

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

151

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

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

163

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

171

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

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

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

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

183

1.1
Location : parseNextToken
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::readUntilEndOfLine → NO_COVERAGE

192

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

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

203

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

223

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

234

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

239

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

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

253

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

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

256

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

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

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

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

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

262

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

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

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

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

264

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

266

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

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

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

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

268

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

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

270

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

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

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

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

272

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

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

278

1.1
Location : parseNextToken
Killed by : none
Replaced integer multiplication with division → NO_COVERAGE

279

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

281

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

289

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

292

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

293

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

2.2
Location : parseNextToken
Killed by : none
removed call to java/lang/System::arraycopy → NO_COVERAGE

303

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

331

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

332

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

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

338

1.1
Location : parseNextToken
Killed by : none
removed call to java/io/PushbackInputStream::unread → NO_COVERAGE

340

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

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

356

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

366

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

372

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

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

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

381

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

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

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

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

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

387

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

2.2
Location : increment
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::increment → NO_COVERAGE

392

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

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

3.3
Location : increment
Killed by : none
Replaced integer modulus with multiplication → NO_COVERAGE

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

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

395

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

2.2
Location : increment
Killed by : none
removed call to com/lowagie/text/pdf/fonts/cmaps/CMapParser::increment → NO_COVERAGE

399

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

406

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

414

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

421

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

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

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

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

423

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

427

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

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

3.3
Location : compare
Killed by : none
Replaced integer modulus with multiplication → NO_COVERAGE

4.4
Location : compare
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

5.5
Location : compare
Killed by : none
Replaced integer modulus with multiplication → NO_COVERAGE

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

438

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

474

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

476

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

477

1.1
Location : main
Killed by : none
removed call to java/lang/System::exit → NO_COVERAGE

481

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

Active mutators

Tests examined


Report generated by PIT 1.4.2