/* * Copyright (C) 2007 Steve Ratcliffe * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program 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 General Public License for more details. * * * Author: Steve Ratcliffe * Create date: Dec 14, 2007 */ package uk.me.parabola.imgfmt.app; import java.io.UnsupportedEncodingException; import java.util.Date; import uk.me.parabola.imgfmt.ReadFailedException; import uk.me.parabola.imgfmt.Utils; /** * The header that is common to all application files within the .img file. * It basically contains two things of interest, the size of the header and * its type. The type is usually of the form 'GARMIN.YYY' where YYY is the * file extension of the type eg TRE, LBL, RGN etc. * * @author Steve Ratcliffe */ public abstract class CommonHeader { protected static final int COMMON_HEADER_LEN = 21; private static final int TYPE_LEN = 10; // The common header contains the length and the type which are set at // construction time. private int headerLength; private String type; // Set to 0x80 on locked maps. We are not interested in creating locked // maps, but may be useful to recognise them for completeness. // private byte lockFlag; // A date of creation. private Date creationDate; protected CommonHeader(int headerLength, String type) { this.headerLength = headerLength; this.type = type; } /** * Writes out the header that is common to all the file types. It should * be called by the sync() methods of subclasses when they are ready. * @param writer Used to write the header. */ public final void writeHeader(ImgFileWriter writer) { writePrepare(); writer.position(0); writer.putChar((char) headerLength); writer.put(Utils.toBytes(type, TYPE_LEN, (byte) 0)); writer.put((byte) 1); // unknown writer.put((byte) 0); // not locked byte[] date = Utils.makeCreationTime(new Date()); writer.put(date); writeFileHeader(writer); } /** * Read the common header. It starts at the beginning of the file. * @param reader Used to read the header. */ public final void readHeader(ImgFileReader reader) throws ReadFailedException { reader.position(0); headerLength = reader.getChar(); byte[] bytes = reader.get(TYPE_LEN); try { type = new String(bytes, "ascii"); } catch (UnsupportedEncodingException e) { // ascii is supported always, so this can't happen } reader.get(); // ignore reader.get(); // ignore byte[] date = reader.get(7); creationDate = Utils.makeCreationTime(date); readFileHeader(reader); } /** * Read the rest of the header. Specific to the given file. It is * guaranteed that the file position will be set to the correct place * before this is called. * @param reader The header is read from here. */ protected abstract void readFileHeader(ImgFileReader reader) throws ReadFailedException; /** * Write the rest of the header. It is guaranteed that the writer will * be set to the correct position before calling. * @param writer The header is written here. */ protected abstract void writeFileHeader(ImgFileWriter writer); public int getHeaderLength() { return headerLength; } private void writePrepare() { // Prepare for write by setting our defaults. // lockFlag = 0; if (creationDate == null) creationDate = new Date(); } }