ContentTypeDetector.java

    1/*******************************************************************************
    2 * Copyright (c) 2009, 2010 Mountainminds GmbH & Co. KG and Contributors
    3 * All rights reserved. This program and the accompanying materials
    4 * are made available under the terms of the Eclipse Public License v1.0
    5 * which accompanies this distribution, and is available at
    6 * http://www.eclipse.org/legal/epl-v10.html
    7 *
    8 * Contributors:
    9 *    Marc R. Hoffmann - initial API and implementation
   10 *    
   11 * $Id: $
   12 *******************************************************************************/
   13package org.jacoco.core.instr;
   14
   15import java.io.BufferedInputStream;
   16import java.io.IOException;
   17import java.io.InputStream;
   18
   19/**
   20 * Detector for content types of binary streams based on a magic headers.
   21 * 
   22 * @author Marc R. Hoffmann
   23 * @version $Revision: $
   24 */
   25class ContentTypeDetector {
   26
   27    /** Header of Java class files */
   28    public static final int CLASSFILE = 0xcafebabe;
   29
   30    /** Header of ZIP files */
   31    public static final int ZIPFILE = 0x504b0304;
   32
   33    private static final int HEADER_SIZE = 4;
   34
   35    private final InputStream in;
   36
   37    private final int header;
   38
   39    /**
   40     * Creates a new detector based on the given input. To process the complete
   41     * original input afterwards use the stream returned by
   42     * {@link #getInputStream()}.
   43     * 
   44     * @param in
   45     *            input to read the header from
   46     * @throws IOException
   47     */
   48    ContentTypeDetector(final InputStream in) throws IOException {
   49        if (in.markSupported()) {
   50            this.in = in;
   51        } else {
   52            this.in = new BufferedInputStream(in, HEADER_SIZE);
   53        }
   54        this.in.mark(HEADER_SIZE);
   55        this.header = readHeader(this.in);
   56        this.in.reset();
   57    }
   58
   59    private static int readHeader(final InputStream in) throws IOException {
   60        return in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read();
   61    }
   62
   63    /**
   64     * Returns an input stream instance to read the complete content (including
   65     * the header) of the underlying stream.
   66     * 
   67     * @return input stream containing the complete content
   68     */
   69    public InputStream getInputStream() {
   70        return in;
   71    }
   72
   73    /**
   74     * Returns the file header containing the magic number.
   75     * 
   76     * @return file header
   77     */
   78    public int getHeader() {
   79        return header;
   80    }
   81
   82}