/* V9t9FDR.java (c) 2008-2015 Edward 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.common.files; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class V9t9FDR extends TIFDR { public static final int FDRSIZE = 128; /** char filenam[10];// filename, padded with spaces u8 res10[2]; // reserved u8 flags; // filetype flags u8 recspersec; // # records per sector, 256/reclen for FIXED, 255/(reclen+1) for VAR, 0 for program u16 secsused; // [big-endian]: # sectors in file u8 byteoffs; // last byte used in file (0 = no last empty sector) u8 reclen; // record length, 0 for program u16 numrecs; // [little-endian]: # records for FIXED file, # sectors for VARIABLE file, 0 for program u8 rec20[8]; // reserved u8 dcpb[100]; // sector layout of file, ignored for v9t9 */ public V9t9FDR() { super(FDRSIZE); } public static V9t9FDR readFDR(File file) throws IOException, InvalidFDRException { V9t9FDR fdr = new V9t9FDR(); FileInputStream stream = new FileInputStream(file); try { stream.read(fdr.filename); stream.read(fdr.res10); fdr.flags = stream.read(); fdr.recspersec = stream.read(); fdr.secsused = (stream.read() << 8) | stream.read(); fdr.byteoffs = stream.read(); fdr.reclen = stream.read(); fdr.numrecs = stream.read() | (stream.read() << 8); stream.read(fdr.rec20); int cnt = stream.read(fdr.dcpb); if (cnt != fdr.dcpb.length) throw new InvalidFDRException("File header is too short; expected 128 bytes"); } finally { stream.close(); } fdr.validate(file); return fdr; } public static V9t9FDR createFDR(byte[] data, int offset) { V9t9FDR fdr = new V9t9FDR(); System.arraycopy(data, offset, fdr.filename, 0, fdr.filename.length); System.arraycopy(data, offset + 0xA, fdr.res10, 0, fdr.res10.length); fdr.flags = data[offset + 0xc] & 0xff; fdr.recspersec = data[offset + 0xd] & 0xff; fdr.secsused = ((data[offset + 0xe] & 0xff) << 8) | (data[offset + 0xf] & 0xff); fdr.byteoffs = data[offset + 0x10] & 0xff; fdr.reclen = data[offset + 0x11] & 0xff; fdr.numrecs = (data[offset + 0x12] & 0xff) | ((data[offset + 0x13] & 0xff) << 8); System.arraycopy(data, offset + 0x14, fdr.rec20, 0, fdr.rec20.length); System.arraycopy(data, offset + 0x1C, fdr.dcpb, 0, fdr.dcpb.length); return fdr; } /** * Set the filename */ public void setFileName(String name) throws IOException { if (name.length() > 10) throw new IOException("Name too long: " + name); for (int i = 0; i < filename.length; i++) { char ch = ' '; if (i < name.length()) ch = name.charAt(i); filename[i] = (byte) ch; } } public byte[] toBytes() { ByteArrayOutputStream os = new ByteArrayOutputStream(128); try { os.write(filename); os.write(res10); os.write(flags); os.write(recspersec); os.write(secsused >> 8); os.write(secsused & 0xff); os.write(byteoffs); os.write(reclen); os.write(numrecs & 0xff); os.write(numrecs >> 8); os.write(rec20); os.write(dcpb); os.close(); } catch (IOException e) { throw new IllegalStateException(e); } return os.toByteArray(); } public String getFileName() { StringBuilder builder = new StringBuilder(); int len = 0; for (int i = 0; i < filename.length; i++) { char ch = (char) filename[i]; if (ch != ' ') len = i; builder.append(ch); } builder.setLength(len + 1); return builder.toString(); } /* (non-Javadoc) * @see v9t9.common.files.FDR#fetchContentSectors() */ @Override protected int[] fetchContentSectors() { int[] secs = new int[getSectorsUsed()]; for (int i = 0; i < secs.length; i++) { secs[i] = 32 + i; } return secs; } /* (non-Javadoc) * @see v9t9.common.files.FDR#setContentSectors(int[]) */ @Override public void setContentSectors(int[] secs) throws IOException { throw new IOException("cannot allocate sectors for V9t9 files"); } /* (non-Javadoc) * @see v9t9.common.files.IFDRInfo#getComment() */ @Override public String getComment() { return null; } }