/*
* 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.lbl;
import java.io.UnsupportedEncodingException;
import uk.me.parabola.imgfmt.app.CommonHeader;
import uk.me.parabola.imgfmt.app.ImgFileReader;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
import uk.me.parabola.imgfmt.app.labelenc.CodeFunctions;
import uk.me.parabola.imgfmt.app.srt.Sort;
/**
* The header for the LBL file.
*
* @author Steve Ratcliffe
*/
public class LBLHeader extends CommonHeader {
public static final int HEADER_LEN = 196; // Other lengths are possible
private static final char UNK3_REC_LEN = 0;
private int labelStart; // Start of labels.
private int labelSize; // Size of file.
private int offsetMultiplier;
// Code page and sorting info.
private Sort sort;
private int sortDescriptionLength;
// The type of encoding employed. This is not a length.
private int encodingType = CodeFunctions.ENCODING_FORMAT6;
// The label section also contains all kinds of records related to place,
// so these have all been put in their own class.
private final PlacesHeader placeHeader;
public LBLHeader() {
super(HEADER_LEN, "GARMIN LBL");
placeHeader = new PlacesHeader();
}
public int getSortDescriptionLength() {
return sortDescriptionLength;
}
/**
* 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 void readFileHeader(ImgFileReader reader) {
labelStart = reader.getInt();
labelSize = reader.getInt();
offsetMultiplier = 1 << reader.get();
encodingType = reader.get();
// Read the places part of the header.
placeHeader.readFileHeader(reader);
int codepage = reader.getChar();
int id1 = reader.getChar();
int id2 = reader.getChar();
int descOff = reader.getInt();
int descLen = reader.getInt();
reader.position(descOff);
byte[] bytes = reader.get(descLen);
String description;
try {
description = new String(bytes, "ascii");
} catch (UnsupportedEncodingException e) {
description = "Unknown";
}
sort = new Sort();
sort.setCodepage(codepage);
sort.setId1(id1);
sort.setId2(id2);
sort.setDescription(description);
// more to do but not needed yet... Just set position
reader.position(labelStart);
}
/**
* 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 void writeFileHeader(ImgFileWriter writer) {
// LBL1 section, these are regular labels
writer.putInt(HEADER_LEN + sortDescriptionLength);
writer.putInt(getLabelSize());
writer.put((byte) offsetMultiplier);
writer.put((byte) encodingType);
placeHeader.writeFileHeader(writer);
writer.putChar((char) getCodePage());
// Identifying the sort
char id1 = (char) sort.getId1();
writer.putChar(id1);
char id2 = (char) sort.getId2();
if (id1 != 0 && id2 != 0)
id2 |= 0x8000;
writer.putChar(id2);
writer.putInt(HEADER_LEN);
writer.putInt(sortDescriptionLength);
writer.putInt(placeHeader.getLastPos());
writer.putInt(0);
writer.putChar(UNK3_REC_LEN);
writer.putChar((char) 0);
}
protected int getEncodingType() {
return encodingType;
}
public void setEncodingType(int type) {
this.encodingType = type;
}
protected int getLabelSize() {
return labelSize;
}
public void setLabelSize(int labelSize) {
this.labelSize = labelSize;
placeHeader.setLabelEnd(HEADER_LEN + sortDescriptionLength + labelSize);
}
protected int getCodePage() {
return sort.getCodepage();
}
public void setSort(Sort sort) {
sortDescriptionLength = sort.getDescription().length() + 1;
this.sort = sort;
}
public int getSortOrderId() {
return sort.getSortOrderId();
}
public int getLabelStart() {
return labelStart;
}
public int getOffsetMultiplier() {
return offsetMultiplier;
}
public PlacesHeader getPlaceHeader() {
return placeHeader;
}
public void setOffsetMultiplier(int offsetMultiplier) {
this.offsetMultiplier = offsetMultiplier;
}
}