/*
Type.java
(c) 2013 Ed Swartz
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
*/
package v9t9.tools;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import v9t9.common.files.DsrException;
import v9t9.common.files.IEmulatedDisk;
import v9t9.common.files.IEmulatedFile;
import v9t9.common.files.NativeTextFile;
import v9t9.common.files.PabConstants;
import v9t9.common.machine.IMachine;
import v9t9.common.memory.ByteMemoryAccess;
import v9t9.engine.files.directory.OpenFile;
import v9t9.tools.utils.BaseDiskUtil;
import v9t9.tools.utils.Category;
import v9t9.tools.utils.ToolUtils;
import ejs.base.logging.LoggingUtils;
import ejs.base.utils.Pair;
import gnu.getopt.Getopt;
/**
* @author ejs
*
*/
@Category(Category.DISKUTILS)
public class Type extends BaseDiskUtil {
private static final String PROGNAME = Type.class.getSimpleName();
private boolean emitRaw;
private static void help() {
System.out.println("\n"
+ "V9t9 File Typer\n"
+ "\n"
+ "Shows the content files in a disk or directory\n"
+ "\n"
+ PROGNAME + " [options] {disk|dir}:namePattern\n"+
"\n"+
"Options:\n"+
"-r: raw output -- suppress newline between each record\n"+
"\n"+
"where 'disk' is a path to a *.dsk or *.trk image and\n"+
"'dir' is a disk directory and\n"+
"'namePattern' is a emulated file (or regex) in that disk or directory"
);
}
public static void main(String[] args) {
LoggingUtils.setupNullLogging();
if (args.length == 0) {
help();
System.exit(0);
}
IMachine machine = ToolUtils.createMachine();
Type typer = new Type(machine, System.out);
Getopt getopt;
getopt = new Getopt(PROGNAME, args, "?r");
int opt;
while ((opt = getopt.getopt()) != -1) {
switch (opt) {
case '?':
help();
break;
case 'r':
typer.setEmitRaw(true);
break;
}
}
try {
// leftover files are FIAD
int idx = getopt.getOptind();
while (idx < args.length) {
String name = args[idx++];
typer.type(name);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void setEmitRaw(boolean b) {
this.emitRaw = b;
}
public Type(IMachine machine, PrintStream out) {
super(machine, out);
}
private void type(String arg) throws IOException {
List<IEmulatedFile> srcFiles = new ArrayList<IEmulatedFile>();
Pair<IEmulatedDisk, String> info = decode(arg);
getSrcFiles(srcFiles, info.first, info.second);
if (srcFiles.isEmpty()) {
System.err.println("no files resolved for " + arg);
return;
}
for (IEmulatedFile srcFile : srcFiles) {
dumpContent(srcFile);
}
}
private void dumpContent(IEmulatedFile file) throws IOException {
OpenFile of = new OpenFile(file, "DSK1", file.getFileName());
try {
if (file instanceof NativeTextFile || of.isProgram()) {
// dump whole thing
byte[] contents = new byte[file.getFileSize()];
file.readContents(contents, 0, 0, contents.length);
out.write(contents);
} else {
byte[] record = new byte[256];
ByteMemoryAccess access = new ByteMemoryAccess(record, 0);
while (true) {
access.offset = 0;
int len = 0;
try {
len = of.readRecord(access, file.getRecordLength());
} catch (DsrException e) {
if (e.getErrorCode() == PabConstants.e_endoffile) {
break;
} else {
throw e;
}
}
if (len <= 0)
break;
out.write(record, 0, len);
if (!emitRaw)
out.println();
}
}
} finally {
of.close();
}
}
}