/*-
 * Copyright (c) 2012-2015 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.fedoraproject.javadeptools.rpm;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.lzma.LZMACompressorInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;

/**
 * A class for reading RPM package as an archive.
 * 
 * @author Mikolaj Izdebski
 */
public class RpmArchiveInputStream extends ArchiveInputStream {
    private final ArchiveInputStream delegate;

    public RpmArchiveInputStream(Path path) throws IOException {
        this.delegate = wrapFile(path);
    }

    @Override
    public void close() throws IOException {
        delegate.close();
    }

    @Override
    public ArchiveEntry getNextEntry() throws IOException {
        return delegate.getNextEntry();
    }

    @Override
    public int read() throws IOException {
        return delegate.read();
    }

    @Override
    public int read(byte[] buf) throws IOException {
        return delegate.read(buf);
    }

    @Override
    public int read(byte[] buf, int off, int len) throws IOException {
        return delegate.read(buf, off, len);
    }

    private static IOException error(Path path, String message) throws IOException {
        throw new IOException("Unable to open RPM file " + path + ": " + message);
    }

    private static boolean hasGzipMagic(InputStream fis) throws IOException {
        try {
            fis.mark(2);
            return fis.read() == 31 && fis.read() == 139;
        } finally {
            fis.reset();
        }
    }

    private static ArchiveInputStream wrapFile(Path path) throws IOException {
        RpmInfo info = new RpmInfo(path);
        InputStream fis = new BufferedInputStream(Files.newInputStream(path));
        fis.skip(info.getHeaderSize());

        InputStream cis;
        switch (info.getCompressionMethod()) {
        case "gzip":
            if (hasGzipMagic(fis))
                cis = new GzipCompressorInputStream(fis, true);
            else
                cis = fis;
            break;
        case "bzip2":
            cis = new BZip2CompressorInputStream(fis);
            break;
        case "xz":
            cis = new XZCompressorInputStream(fis);
            break;
        case "lzma":
            cis = new LZMACompressorInputStream(fis);
            break;
        default:
            fis.close();
            throw error(path, "Unsupported compression method: " + info.getCompressionMethod());
        }

        ArchiveInputStream ais;
        switch (info.getArchiveFormat()) {
        case "cpio":
            ais = new CpioArchiveInputStream(cis);
            break;
        default:
            cis.close();
            throw error(path, "Unsupported archive format: " + info.getArchiveFormat());
        }

        return ais;
    }

}

@@ -25,10 +25,10 @@
 2-20
-15
+20
  Red
@@ -797,67 +797,8 @@
 h;%0A%0A
-import org.apache.commons.compress.archivers.ArchiveEntry;%0A
 impo
@@ -850,32 +850,100 @@
 iveInputStream;%0A
+import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry;%0A
 import org.apach
@@ -1487,16 +1487,20 @@
 e final 
+Cpio
 ArchiveI
@@ -1750,16 +1750,20 @@
  public 
+Cpio
 ArchiveE
@@ -1830,24 +1830,28 @@
 gate.getNext
+CPIO
 Entry();%0A   
@@ -2627,16 +2627,20 @@
  static 
+Cpio
 ArchiveI
@@ -3550,48 +3550,13 @@
     
-ArchiveInputStream ais;%0A        switch
+if
  (
+!
 info
@@ -3578,119 +3578,26 @@
 at()
-) %7B%0A        case %22cpio%22:%0A            ais = new CpioArchiveInputStream(cis);%0A            break;%0A        default:
+.equals(%22cpio%22)) %7B
 %0A   
@@ -3737,11 +3737,39 @@
 urn 
-a
+new CpioArchiveInputStream(c
 is
+)
 ;%0A  

Make RpmArchiveInputStream expose cpio entries