/**
* This file is part of muCommander, http://www.mucommander.com
* Copyright (C) 2002-2016 Maxence Bernard
*
* muCommander is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* muCommander is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.mucommander.commons.file.archive.sevenzip;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mucommander.commons.file.AbstractFile;
import com.mucommander.commons.file.UnsupportedFileOperationException;
import com.mucommander.commons.file.archive.AbstractROArchiveFile;
import com.mucommander.commons.file.archive.ArchiveEntry;
import com.mucommander.commons.file.archive.ArchiveEntryIterator;
import com.mucommander.commons.file.archive.WrapperArchiveEntryIterator;
import com.mucommander.commons.file.archive.sevenzip.provider.SevenZip.Archive.IInArchive;
import com.mucommander.commons.file.archive.sevenzip.provider.SevenZip.Archive.SevenZipEntry;
import com.mucommander.commons.file.archive.sevenzip.provider.SevenZip.Archive.SevenZip.Handler;
import com.mucommander.commons.util.CircularByteBuffer;
/**
* SevenZipArchiveFile provides read access to archives in the 7zip format.
*
* @author Arik Hadas, Maxence Bernard
*/
public class SevenZipArchiveFile extends AbstractROArchiveFile {
private static final Logger LOGGER = LoggerFactory.getLogger(SevenZipArchiveFile.class);
private IInArchive sevenZipFile;
public SevenZipArchiveFile(AbstractFile file) throws IOException {
super(file);
}
private IInArchive openSevenZipFile() throws IOException {
if (sevenZipFile == null) {
MuRandomAccessFile in = new MuRandomAccessFile(file);
// MyRandomAccessFile in = new MyRandomAccessFile(file.getAbsolutePath(), "rw");
sevenZipFile = new Handler();
if (sevenZipFile.Open(in) != 0)
throw new IOException("Error while opening 7zip archive " + file.getAbsolutePath());
}
return sevenZipFile;
}
/**
* Creates and return an {@link ArchiveEntry()} whose attributes are fetched from the given {@link SevenZipEntry}
*
* @param entry the object that serves to initialize the attributes of the returned ArchiveEntry
* @return an ArchiveEntry whose attributes are fetched from the given SevenZipEntry
*/
private ArchiveEntry createArchiveEntry(SevenZipEntry entry) {
return new ArchiveEntry(entry.getName(), entry.isDirectory(), entry.getTime(), entry.getSize(), true);
}
//////////////////////////////////////////
// AbstractROArchiveFile implementation //
//////////////////////////////////////////
@Override
public InputStream getEntryInputStream(final ArchiveEntry entry, ArchiveEntryIterator entryIterator) throws IOException, UnsupportedFileOperationException {
final IInArchive sevenZipFile = openSevenZipFile();
/* ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
// threadPool.execute(new Runnable() {
// public void run() {
// BufferedOutputStream bufferedOut = new BufferedOutputStream(out);
try {
int arrays [] = new int[1];
for(int i = 0 ; i < sevenZipFile.size() ; i++) {
// System.out.println("check " + sevenZipFile.getEntry(i).getName());
if (entry.getPath().equals(sevenZipFile.getEntry(i).getName())) {
System.out.println("entry.getPath = " + entry.getPath() + ", sevenZipFile.getEntry(i).getName() " + sevenZipFile.getEntry(i).getName());
arrays[0] = i;
break;
}
}
MuArchiveExtractCallback extractCallbackSpec = new MuArchiveExtractCallback(os);//, entry.getPath());
extractCallbackSpec.Init(sevenZipFile);
try {
sevenZipFile.Extract(arrays, 1, IInArchive.NExtract_NAskMode_kExtract , extractCallbackSpec);
}
catch (Exception e) {
e.printStackTrace();
// return;
}
// sevenZipFile.Extract(null, -1, IInArchive.NExtract_NAskMode_kExtract , extractCallbackSpec);
try
{
Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println("stopped");
// bufferedOut.flush();
}
catch (Exception e) {
LOGGER.info("Error while retrieving 7zip entry {}", e);
System.out.println("Error while retrieving 7zip entry {}");
}
finally {
// try { bufferedOut.close(); }
// catch(IOException e) {
// // Not much we can do about it
// e.printStackTrace();
// }
try { in.close(); }
catch(IOException e) {
// Not much we can do about it
e.printStackTrace();
}
try { sevenZipFile.close(); }
catch(IOException e) {
// Not much we can do about it
e.printStackTrace();
}
}
// }
// });
return new ByteArrayInputStream(os.toByteArray()); */
final int arrays [] = new int[1];
for(int i = 0 ; i < sevenZipFile.size() ; i++) {
// System.out.println("check " + sevenZipFile.getEntry(i).getName());
if (entry.getPath().equals(sevenZipFile.getEntry(i).getName())) {
System.out.println("entry.getPath = " + entry.getPath() + ", sevenZipFile.getEntry(i).getName() " + sevenZipFile.getEntry(i).getName());
arrays[0] = i;
break;
}
}
final CircularByteBuffer cbb = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE);
new Thread(
new Runnable(){
public void run(){
MuArchiveExtractCallback extractCallbackSpec = new MuArchiveExtractCallback(cbb.getOutputStream(), entry.getPath());
extractCallbackSpec.Init(sevenZipFile);
try {
sevenZipFile.Extract(arrays, 1, IInArchive.NExtract_NAskMode_kExtract , extractCallbackSpec);
}
catch (Exception e) {
e.printStackTrace();
// return;
}
}
}
).start();
return cbb.getInputStream();
}
@Override
public ArchiveEntryIterator getEntryIterator() throws IOException {
final IInArchive sevenZipFile = openSevenZipFile();
try {
int nbEntries = sevenZipFile.size();
Vector<ArchiveEntry> entries = new Vector<ArchiveEntry>();
for(int i = 0; i <nbEntries ; i++)
entries.add(createArchiveEntry(sevenZipFile.getEntry(i)));
return new WrapperArchiveEntryIterator(entries.iterator());
}
finally {
/*try { sevenZipFile.close(); }
catch(IOException e) {
// Not much we can do about it
}*/
}
}
}