/**
* 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.lst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mucommander.commons.file.archive.ArchiveEntry;
import com.mucommander.commons.file.archive.ArchiveEntryIterator;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.StringTokenizer;
/**
* An <code>ArchiveEntryIterator</code> that iterates through an LST archive.
*
* @author Maxence Bernard
*/
class LstArchiveEntryIterator implements ArchiveEntryIterator {
private static final Logger LOGGER = LoggerFactory.getLogger(LstArchiveEntryIterator.class);
/** Allows to read the LST archive line by line */
private BufferedReader br;
/** Parses LST-formatted dates */
private SimpleDateFormat lstDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm.ss");
/** The next entry to be returned by #nextEntry(), null if there is no more entry */
private ArchiveEntry nextEntry;
/** Base folder of all entries */
private String baseFolder;
/** Current directory, used for parsing the LST file */
private String currentDir = "";
/**
* Creates a new <code>LstArchiveEntryIterator</code> that parses the given LST <code>InputStream</code>.
* The <code>InputStream</code> will be closed by {@link #close()}.
*
* @param in an LST archive <code>InputStream</code>
* @throws IOException if an I/O error occurred while initializing this iterator
*/
LstArchiveEntryIterator(InputStream in) throws IOException {
br = new BufferedReader(new InputStreamReader(in));
// Read the base folder
baseFolder = br.readLine();
if(baseFolder==null)
throw new IOException();
}
/**
* Reads the next entry and returns an {@link ArchiveEntry} representing it.
*
* @return an ArchiveEntry representing the entry
* @throws IOException if an error occurred
*/
ArchiveEntry getNextEntry() throws IOException {
String line = br.readLine();
if(line==null)
return null;
try {
StringTokenizer st = new StringTokenizer(line, "\t");
String name = st.nextToken().replace('\\', '/');
long size = Long.parseLong(st.nextToken());
long date = lstDateFormat.parse((st.nextToken()+" "+st.nextToken())).getTime();
String path;
boolean isDirectory;
if(name.endsWith("/")) {
isDirectory = true;
currentDir = name;
path = currentDir;
}
else {
isDirectory = false;
path = currentDir+name;
}
return new LstArchiveEntry(path, isDirectory, date, size, baseFolder);
}
catch(Exception e) { // Catches exceptions thrown by StringTokenizer and SimpleDateFormat
LOGGER.info("Exception caught while parsing LST file", e);
throw new IOException();
}
}
/////////////////////////////////////////
// ArchiveEntryIterator implementation //
/////////////////////////////////////////
public ArchiveEntry nextEntry() throws IOException {
// Return the next entry, if any
return getNextEntry();
}
public void close() throws IOException {
br.close();
}
}