package org.codehaus.mojo.deb.jdpkg.ar;
import static org.codehaus.mojo.deb.jdpkg.ar.ArUtil.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @author <a href="mailto:trygve.laugstol@arktekk.no">Trygve Laugstøl</a>
* @version $Id$
*/
class ArReader implements CloseableIterable<ReadableArFile> {
private InputStream is;
public ArReader(File file) throws IOException {
is = new FileInputStream(file);
String magic = new String(readBytes(is, 8), US_ASCII);
if (!magic.equals(AR_ARCHIVE_MAGIC)) {
throw new InvalidArchiveMagicException();
}
}
public Iterator<ReadableArFile> iterator() {
return new ArFileIterator();
}
public void close() {
closeSilent(is);
}
public ReadableArFile readFile() throws IOException {
byte[] bytes = readBytes(is, 60);
if (bytes == null) {
return null;
}
ReadableArFile arFile = new ReadableArFile(is);
arFile.name = convertString(bytes, 0, 16);
arFile.lastModified = Long.parseLong(convertString(bytes, 16, 12));
arFile.ownerId = Integer.parseInt(convertString(bytes, 28, 6));
arFile.groupId = Integer.parseInt(convertString(bytes, 34, 6));
arFile.mode = Integer.parseInt(convertString(bytes, 40, 8), 8);
arFile.size = Long.parseLong(convertString(bytes, 48, 10));
String fileMagic = convertString(bytes, 58, 2);
if (!fileMagic.equals(AR_FILE_MAGIC)) {
throw new InvalidFileMagicException();
}
return arFile;
}
public class ArFileIterator implements Iterator<ReadableArFile> {
private boolean used;
private boolean atEnd;
private ReadableArFile file;
public boolean hasNext() {
updateNext();
return file != null;
}
public ReadableArFile next() {
updateNext();
if (file == null) {
throw new NoSuchElementException();
}
used = true;
return file;
}
private void updateNext() {
try {
if (used) {
file.close();
file = null;
used = false;
}
// There already is an element ready
if (file != null) {
return;
}
// If we're at the end, don't call readFile() anymore as that will throw an IOException
if (atEnd) {
return;
}
file = readFile();
atEnd = file == null;
if (atEnd) {
close();
}
}
catch (IOException ex) {
// ignore
}
}
public void remove() {
throw new UnsupportedOperationException("Not implemented.");
}
}
}