Subversion Repositories display

Rev

Rev 307 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package test.display;

import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.app.BufferedImgFileReader;
import uk.me.parabola.imgfmt.app.ImgFileReader;
import uk.me.parabola.imgfmt.app.lbl.LBLFileReader;
import uk.me.parabola.imgfmt.app.net.NETFileReader;
import uk.me.parabola.imgfmt.app.trergn.TREFileReader;
import uk.me.parabola.imgfmt.fs.DirectoryEntry;
import uk.me.parabola.imgfmt.fs.FileSystem;
import uk.me.parabola.imgfmt.fs.ImgChannel;
import uk.me.parabola.imgfmt.sys.FileImgChannel;
import uk.me.parabola.imgfmt.sys.ImgFS;

import test.files.RgnFile;

/**
 * Common code for files that have the 'common header' in a .img file.
 */

public abstract class CommonDisplay {
        public static final int COMMON_HEADER_LEN = 21;

        // You will always have a reader.
        protected ImgFileReader reader;

        // You may not have a filesystem.
        private FileSystem fs;

        protected PrintStream outStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)));
        private int headerLen;
        protected long filelen;

        // The sections in the file, if any.
        protected SectList sections = new SectList();

        protected LBLFileReader lbl;
        protected TREFileReader tre;
        protected RgnFile rgn;
        protected NETFileReader net;

        protected abstract void print();

        protected void readCommonHeader() {

                Displayer d = new Displayer(reader);
                d.setTitle("Common Header");

                headerLen = d.charValue("Header length %d");
                d.stringValue(10, "File type %s");

                d.byteValue("???");
                d.byteValue("Set if locked");

                DisplayItem item = d.rawItem(7);
        Date date = Utils.makeCreationTime(item.getBytes());
        DateFormat df = new SimpleDateFormat("HH:mm:ss d MMM yyyy");
        item.addText(df.format(date));

        d.print(outStream);
        }

        protected void readHeaderLen() {
                reader.position(0);
                headerLen = reader.getChar();
                reader.position(COMMON_HEADER_LEN);
        }

        /**
         * Read the common combination offset + size (+ record size) in file headers.
         * Utility function for subclasses.
         *
         * @param d The Displayer to use.
         * @param name The name of the subfile.
         * @param number The section number.
         * @param hasRecSize There is a record size to be read.
         * @param hasMagic Has an 4 byte integer value following the header information. Otherwise
         * false and any extra values must be read explicitly.
         * @return The section information.  It has also been saved for retrieval with getSection.
         */

        protected Section readSection(Displayer d, String name, int number, boolean hasRecSize, boolean hasMagic) {
                assert number != 0;

                d.gap();
               
                int start = d.intValue(name + " at offset %#08x");
                int len = d.intValue(name + " length %d");
                Section section = new Section(name, start, len);
                d.item().addText("End of section %08x, len %#08x", start + len, len);

                if (hasRecSize) {
                        int recordSize = d.charValue(name + " record size %02x");
                        if (recordSize != 0) {
                                //assert len % recordSize == 0 : "sect" + number + ", len=" + len + ", recsize=" + recordSize;
                                d.item().addText("Number of records %d", len / recordSize);
                                if (len % recordSize != 0)
                                        d.item().addText("FRACTIONAL RECORD");
                        }
                        section.setRecordSize(recordSize);
                }

                if (hasMagic) {
                        int magic = d.intValue(name + " header flags %04x");
                        section.setMagic(magic);
                }

                while (sections.size() < number-1)
                        sections.add(null);
                sections.add(number-1, section);
                return section;
        }

        protected Section getSection(int n) {
                assert n != 0;
                return sections.get(n-1);
        }

        protected int numberOfSections() {
                return sections.size();
        }


        /**
         * This is used when you want to open a plain file.
         * @param name The name of the file to open.
         */

        protected void display(String name) {
                RandomAccessFile raf = null;
                try {
                        raf = new RandomAccessFile(name, "r");
                        filelen = raf.length();
                        ImgChannel chan = new FileImgChannel(raf.getChannel());
                        this.reader = new BufferedImgFileReader(chan);
                        print();
                        outStream.flush();
                } catch (FileNotFoundException e) {
                        System.err.println("Could not open file: " + name);
                } catch (IOException e) {
                        System.err.println("Could not get file size or read file " + name);
                } finally {
                        if (raf != null) {
                                try {
                                        raf.close();
                                } catch (IOException e) {
                                        // ok
                                }
                        }
                }
        }

        /**
         * This is used to open a file within an img file.
         *
         * @param name The name of the .img file.
         * @param fileExt The file to get.  It is found by extension.
         */

        protected void display(String name, String fileExt) {
                if (name.toLowerCase().endsWith(fileExt.toLowerCase())) {
                        display(name);
                        return;
                }
               
                try {
                        fs = ImgFS.openFs(name);
                        ImgChannel chan = findFile(fileExt);
                        this.reader = new BufferedImgFileReader(chan);
                        print();
                        outStream.flush();
                } catch (FileNotFoundException e) {
                        System.err.println("Could not open file: " + name);
                } finally {
                        if (fs != null) {
                                fs.close();
                        }
                }
        }

        protected ImgChannel findFile(String fileExt) throws FileNotFoundException {
                if (fs == null)
                        throw new FileNotFoundException("Not an img file");
               
                List<DirectoryEntry> entries = fs.list();
                ImgChannel chan = null;
                for (DirectoryEntry ent : entries) {
                        if (ent.getExt().equals(fileExt)) {
                                filelen = ent.getSize();
                                chan = fs.open(ent.getFullName(), "r");
                        }
                }

                if (chan == null)
                        throw new FileNotFoundException("No file with " + fileExt + " extension");
               
                return chan;
        }

        protected void openLbl() {
                try {
                        ImgChannel chan = findFile("LBL");
                        lbl = new LBLFileReader(chan);

                } catch (FileNotFoundException e) {
                        System.err.println("Could not open LBL file");
                }
        }

        protected String fetchLabel(int laboff) {
                if (lbl == null)
                        return "";
                return lbl.fetchLabel(laboff).getText();
        }


        protected void openTre() {
                try {
                        ImgChannel chan = findFile("TRE");
                        tre = new TREFileReader(chan);
                } catch (FileNotFoundException e) {
                        System.err.println("Could not open TRE file");
                }
        }
        protected void openRgn() {
                if (lbl == null)
                        openLbl();

                try {
                        ImgChannel chan = findFile("RGN");
                        rgn = new RgnFile(chan);
                        rgn.setLblFile(lbl);
                } catch (FileNotFoundException e) {
                        System.err.println("Could not open RGN file");
                }
        }

        protected void openNet() {
                try {
                        ImgChannel chan = findFile("NET");
                        net = new NETFileReader(chan);
                } catch (FileNotFoundException e) {
                        System.err.println("Could not open RGN file");
                }
        }

        protected void setOutStream(PrintStream outStream) {
                this.outStream = outStream;
        }

        protected int getHeaderLen() {
                return headerLen;
        }

        protected void analyze(PrintStream outStream) {
                sections.analyze(outStream);
        }

        protected void addSection(Section section) {
                sections.add(section);
        }


}