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 *******************************************************************************/
   12package org.jacoco.core.instr;
   13
   14import java.io.BufferedInputStream;
   15import java.io.IOException;
   16import java.io.InputStream;
   17
   18/**
   19 * Detector for content types of binary streams based on a magic headers.
   20 * 
   21 * @author Marc R. Hoffmann
   22 * @version 0.4.1.20101007204400
   23 */
   24class ContentTypeDetector {
   25
   26    /** Header of Java class files */
   27    public static final int CLASSFILE = 0xcafebabe;
   28
   29    /** Header of ZIP files */
   30    public static final int ZIPFILE = 0x504b0304;
   31
   32    private static final int HEADER_SIZE = 4;
   33
   34    private final InputStream in;
   35
   36    private final int header;
   37
   38    /**
   39     * Creates a new detector based on the given input. To process the complete
   40     * original input afterwards use the stream returned by
   41     * {@link #getInputStream()}.
   42     * 
   43     * @param in
   44     *            input to read the header from
   45     * @throws IOException
   46     */
   47    ContentTypeDetector(final InputStream in) throws IOException {
   48        if (in.markSupported()) {
   49            this.in = in;
   50        } else {
   51            this.in = new BufferedInputStream(in, HEADER_SIZE);
   52        }
   53        this.in.mark(HEADER_SIZE);
   54        this.header = readHeader(this.in);
   55        this.in.reset();
   56    }
   57
   58    private static int readHeader(final InputStream in) throws IOException {
   59        return in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read();
   60    }
   61
   62    /**
   63     * Returns an input stream instance to read the complete content (including
   64     * the header) of the underlying stream.
   65     * 
   66     * @return input stream containing the complete content
   67     */
   68    public InputStream getInputStream() {
   69        return in;
   70    }
   71
   72    /**
   73     * Returns the file header containing the magic number.
   74     * 
   75     * @return file header
   76     */
   77    public int getHeader() {
   78        return header;
   79    }
   80
   81}