Hi

Attached is the first version of the TYP file compiler, using code
written by Thomas Lußnig in 2008 to write the TYP file, which has been
lying unused in mkgmap since then.

It only writes the polygon draw order, so not much use yet, but I expect
to be adding the other sections quickly. It reads any valid typ text
file, or at least it will read: http://code.google.com/p/mkgmap-style-sheets/source/browse/trunk/typ/world-test/default.txt

So to use it, first compile a jar as normal. Then run the following
command (you can not use the -jar option in this case)

java -cp dist/mkgmap.jar uk.me.parabola.mkgmap.typ.TypTextReader <in> <out>

 <in> defaults to "default.txt"
 <out> defaults to "OUT.TYP"

This method of running it is temporary and may even go away at some
point.

I will check the code in to trunk, since it is completely separate from anything else in mkgmap.

..Steve
Index: src/uk/me/parabola/imgfmt/app/typ/ShapeStacking.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/ShapeStacking.java	(revision 2063)
+++ src/uk/me/parabola/imgfmt/app/typ/ShapeStacking.java	(revision )
@@ -16,9 +16,49 @@
  */
 package uk.me.parabola.imgfmt.app.typ;
 
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import uk.me.parabola.imgfmt.app.ImgFileWriter;
+
 /**
+ * Holds the shape stacking section.
+ *
+ * Deals with sorting everything correctly, so no need to sort in the input file.
+ * 
  * @author Steve Ratcliffe
  */
 public class ShapeStacking {
-	// TODO give in content
+	private final SortedMap<Integer, DrawOrder> bar = new TreeMap<Integer, DrawOrder>();
+
+	public void addPolygon(int level, int type, int subtype) {
+		int levelType = (level << 16) + type;
+		DrawOrder order = bar.get(levelType);
+		if (order == null) {
+			order = new DrawOrder((byte) type);
+			bar.put(levelType, order);
-}
+		}
+		
+		order.addSubtype(subtype);
+	}
+
+	public void write(ImgFileWriter writer) {
+		int lastLevel = 1;
+
+		DrawOrder empty = new DrawOrder(0);
+
+		for (Map.Entry<Integer, DrawOrder> ent : bar.entrySet()) {
+			int level = (ent.getKey() >> 16) & 0xffff;
+			DrawOrder order = ent.getValue();
+
+			if (level != lastLevel) {
+				empty.write(writer);
+				lastLevel = level;
+			}
+
+			order.write(writer);
+		}
+	}
+
+}
Index: src/uk/me/parabola/mkgmap/typ/TypTextReader.java
===================================================================
--- src/uk/me/parabola/mkgmap/typ/TypTextReader.java	(revision )
+++ src/uk/me/parabola/mkgmap/typ/TypTextReader.java	(revision )
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * 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.
+ */
+package uk.me.parabola.mkgmap.typ;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.io.Reader;
+import java.nio.channels.FileChannel;
+
+import uk.me.parabola.imgfmt.app.typ.ShapeStacking;
+import uk.me.parabola.imgfmt.app.typ.TYPFile;
+import uk.me.parabola.imgfmt.app.typ.TypParam;
+import uk.me.parabola.imgfmt.sys.FileImgChannel;
+import uk.me.parabola.mkgmap.scan.SyntaxException;
+import uk.me.parabola.mkgmap.scan.TokType;
+import uk.me.parabola.mkgmap.scan.Token;
+import uk.me.parabola.mkgmap.scan.TokenScanner;
+
+/**
+ * Read in a TYP file in the text format.
+ *
+ * @author Steve Ratcliffe
+ */
+public class TypTextReader {
+
+	private final TypParam param = new TypParam();
+	private final ShapeStacking stacking = new ShapeStacking();
+
+	public void read(String filename, Reader r) {
+		TokenScanner scanner = new TokenScanner(filename, r);
+
+		ProcessMethod currentSection = null;
+
+		while (!scanner.isEndOfFile()) {
+			Token tok = scanner.nextToken();
+
+			// We deal with whole line comments here
+			if (tok.isValue(";")) {
+				scanner.skipLine();
+				continue;
+			}
+
+			if (tok.getType() == TokType.SYMBOL) {
+				switch (tok.getValue().charAt(0)) {
+				case ';':
+					scanner.skipLine();
+					break;
+				case '[':
+					ProcessMethod newMethod = readSectionType(scanner);
+					if (currentSection != null)
+						currentSection.finish();
+					currentSection = newMethod;
+					break;
+				case '"':
+					scanner.skipLine();
+					break;
+				}
+			} else {
+				// Line inside a section
+				String name = tok.getValue();
+
+				String sep = scanner.nextValue();
+				if (!sep.equals("=") && !sep.equals(":"))
+					throw new SyntaxException(scanner, "Expecting '=' or ':' instead of " + sep);
+
+				String value = scanner.readLine();
+
+				if (currentSection == null)
+					throw new SyntaxException(scanner, "Missing section start");
+
+				currentSection.processLine(scanner, name, value);
+			}
+			scanner.skipSpace();
+		}
+	}
+
+	private ProcessMethod readSectionType(TokenScanner scanner) {
+		String sectionName = scanner.nextValue().toLowerCase();
+		scanner.validateNext("]"); // Check for closing bracket
+
+		if ("_id".equals(sectionName)) {
+			return new ProcessMethod() {
+				public void processLine(TokenScanner scanner, String name, String value) {
+					idSection(scanner, name, value);
+				}
+
+				public void finish() {
+				}
+			};
+
+		} else if ("_draworder".equals(sectionName)) {
+			return new ProcessMethod() {
+				public void processLine(TokenScanner scanner, String name, String value) {
+					drawOrderSection(scanner, name, value);
+				}
+
+				public void finish() {
+				}
+			};
+
+		} else if ("_point".equals(sectionName)) {
+			return new ProcessMethod() {
+				public void processLine(TokenScanner scanner, String name, String value) {
+					pointSection(scanner, name, value);
+				}
+
+				public void finish() {
+				}
+			};
+
+		} else if ("_line".equals(sectionName)) {
+			return new ProcessMethod() {
+				public void processLine(TokenScanner scanner, String name, String value) {
+					lineSection(scanner, name, value);
+				}
+
+				public void finish() {
+				}
+			};
+
+		} else if ("_polygon".equals(sectionName)) {
+			return new ProcessMethod() {
+				public void processLine(TokenScanner scanner, String name, String value) {
+					polygonSection(scanner, name, value);
+				}
+
+				public void finish() {
+				}
+			};
+
+		} else if ("end".equals(sectionName)) {
+			return null;
+		}
+
+		throw new SyntaxException(scanner, "Unrecognised section name: " + sectionName);
+	}
+
+	private void idSection(TokenScanner scanner, String name, String value) {
+		int ival;
+		try {
+			ival = Integer.parseInt(value);
+		} catch (NumberFormatException e) {
+			throw new SyntaxException(scanner, "Bad integer " + value);
+		}
+
+		if (name.equals("FID")) {
+			param.setFamilyId(ival);
+		} else if (name.equals("ProductCode")) {
+			param.setProductId(ival);
+		} else if (name.equals("CodePage")) {
+			param.setCodePage(ival);
+		} else {
+			throw new SyntaxException(scanner, "Unrecognised keyword in id section: " + name);
+		}
+
+	}
+
+	private void drawOrderSection(TokenScanner scanner, String name, String value) {
+		if (!name.equals("Type"))
+			throw new SyntaxException(scanner, "Unrecognised keyword in draw order section: " + name);
+
+		String[] foo = value.split(",");
+		if (foo.length != 2)
+			throw new SyntaxException(scanner, "Unrecognised drawOrder type " + value);
+
+		int fulltype = Integer.decode(foo[0]);
+		int type;
+		int subtype = 0;
+
+		if (fulltype > 0x10000) {
+			type = (fulltype >> 8) & 0xff;
+			subtype = fulltype & 0xff;
+		} else {
+			type = fulltype & 0xff;
+		}
+
+		int level = Integer.parseInt(foo[1]);
+		stacking.addPolygon(level, type, subtype);
+	}
+
+	private void pointSection(TokenScanner scanner, String name, String value) {
+		if (commonKey(scanner, name, value))
+			return;
+	}
+
+	private void lineSection(TokenScanner scanner, String name, String value) {
+		if (commonKey(scanner, name, value))
+			return;
+	}
+
+	private void polygonSection(TokenScanner scanner, String name, String value) {
+		if (commonKey(scanner, name, value))
+			return;
+	}
+
+	private boolean commonKey(TokenScanner scanner, String name, String value) {
+		return false;
+	}
+
+	public TypParam getParam() {
+		return param;
+	}
+
+	public ShapeStacking getStacking() {
+		return stacking;
+	}
+
+	interface ProcessMethod {
+		public void processLine(TokenScanner scanner, String name, String value);
+
+		public void finish();
+	}
+
+	public static void main(String[] args) throws IOException {
+		String in = "default.txt";
+		if (args.length > 0)
+			in = args[0];
+		String out = "OUT.TYP";
+		if (args.length > 1)
+			out = args[1];
+
+		Reader r = new BufferedReader(new FileReader(in));
+
+		TypTextReader tr = new TypTextReader();
+		try {
+			tr.read(in, r);
+		} catch (SyntaxException e) {
+			System.out.println(e.getMessage());
+		}
+
+		RandomAccessFile raf = new RandomAccessFile(out, "rw");
+		FileChannel channel = raf.getChannel();
+		channel.truncate(0);
+		
+		FileImgChannel w = new FileImgChannel(channel);
+		TYPFile typ = new TYPFile(w);
+		typ.setTypParam(tr.param);
+		typ.setStacking(tr.stacking);
+
+		typ.write();
+		typ.close();
+	}
+}
Index: test/func/lib/ArrayImgWriter.java
===================================================================
--- test/func/lib/ArrayImgWriter.java	(revision )
+++ test/func/lib/ArrayImgWriter.java	(revision )
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * 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.
+ */
+package func.lib;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import uk.me.parabola.imgfmt.app.ImgFileWriter;
+
+/**
+ * A writer that just writes to an array for testing.
+ *
+ * @author Steve Ratcliffe
+ */
+public class ArrayImgWriter implements ImgFileWriter {
+	private final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+	public void sync() throws IOException {
+	}
+
+	public int position() {
+		return out.size();
+	}
+
+	public void position(long pos) {
+		throw new UnsupportedOperationException();
+	}
+
+	public void put(byte b) {
+		out.write(b);
+	}
+
+	public void putChar(char c) {
+		out.write(c & 0xff);
+		out.write((c >> 8) & 0xff);
+	}
+
+	public void put3(int val) {
+		out.write(val & 0xff);
+		out.write((val >> 8) & 0xff);
+		out.write((val >> 16) & 0xff);
+	}
+
+	public void putInt(int val) {
+		out.write(val & 0xff);
+		out.write((val >> 8) & 0xff);
+		out.write((val >> 16) & 0xff);
+		out.write((val >> 24) & 0xff);
+	}
+
+	public void put(byte[] val) {
+		out.write(val, 0, val.length);
+	}
+
+	public void put(byte[] src, int start, int length) {
+		out.write(src, start, length);
+	}
+
+	public void put(ByteBuffer src) {
+		byte[] array = src.array();
+		out.write(array, 0, array.length);
+	}
+
+	public long getSize() {
+		return out.size();
+	}
+
+	public void close() throws IOException {
+		out.close();
+	}
+
+	public byte[] getBytes() {
+		return out.toByteArray();
+	}
+}
Index: src/uk/me/parabola/imgfmt/app/typ/TYPFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TYPFile.java	(revision 2063)
+++ src/uk/me/parabola/imgfmt/app/typ/TYPFile.java	(revision )
@@ -26,9 +26,11 @@
 import java.util.List;
 import java.util.Map;
 
-import uk.me.parabola.imgfmt.app.BufferedImgFileReader;
+import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.BufferedImgFileWriter;
 import uk.me.parabola.imgfmt.app.ImgFile;
+import uk.me.parabola.imgfmt.app.ImgFileWriter;
+import uk.me.parabola.imgfmt.app.SectionWriter;
 import uk.me.parabola.imgfmt.app.Writeable;
 import uk.me.parabola.imgfmt.fs.ImgChannel;
 import uk.me.parabola.log.Logger;
@@ -46,59 +48,56 @@
 	private final List<BitmapImage> images = new LinkedList<BitmapImage>();
 	private final List<PointInfo> pointInfo = new LinkedList<PointInfo>();
 	private final List<DrawOrder> drawOrder = new LinkedList<DrawOrder>();
+	private ShapeStacking stacking;
 
-	public TYPFile(ImgChannel chan, boolean write) {
+	public TYPFile(ImgChannel chan) {
 		setHeader(header);
-		if (write) {
-			setWriter(new BufferedImgFileWriter(chan));
-			position(TYPHeader.HEADER_LEN);
+		setWriter(new BufferedImgFileWriter(chan));
+		position(TYPHeader.HEADER_LEN);
-		} else {
-			setReader(new BufferedImgFileReader(chan));
-			header.readHeader(getReader());
-		}
+	}
-	}
 
-	public void setCodePage(char code) {
-		header.setCodePage(code);
+	public void setCodePage(int code) {
+		header.setCodePage((char) code);
 	}
 
-	public void setFamilyId(char code) {
-		header.setFamilyId(code);
+	public void setFamilyId(int code) {
+		header.setFamilyId((char) code);
 	}
 
-	public void setProductId(char code) {
-		header.setProductId(code);
+	public void setProductId(int code) {
+		header.setProductId((char) code);
 	}
 
 	public void write() {
 		// HEADER_LEN => 1. Image
 		Collections.sort(images, BitmapImage.comperator());
 
-		getWriter().position(TYPHeader.HEADER_LEN);
+		ImgFileWriter writer = getWriter();
+		writer.position(TYPHeader.HEADER_LEN);
 
-		int pos = getWriter().position();
+		int pos = writer.position();
 		header.getPointData().setPosition(pos);
 
 		for (Writeable w : images)
-			w.write(getWriter());
-		int len = getWriter().position() - pos;
+			w.write(writer);
+		int len = writer.position() - pos;
 		header.getPointData().setSize(len);
 
 		if (len < 0x100)
 			header.getPointIndex().setItemSize((char) 3);
-		pos = getWriter().position();
+		pos = writer.position();
 		for (PointInfo w : pointInfo)
-			w.write(getWriter(), header.getPointData().getSize());
-		header.getPointIndex().setSize(getWriter().position() - pos);
+			w.write(writer, header.getPointData().getSize());
+		header.getPointIndex().setSize(writer.position() - pos);
 
-		pos = getWriter().position();
-		for (Writeable w : drawOrder)
-			w.write(getWriter());
-		header.getShapeStacking().setSize(getWriter().position() - pos);
-
+		SectionWriter subWriter = null;
+		try {
+			subWriter = header.getShapeStacking().makeSectionWriter(writer);
+			stacking.write(subWriter);
+		} finally {
+			Utils.closeFile(subWriter);
-	}
+		}
 
-	public void writePost() {
 		log.debug("syncing TYP file");
 		position(0);
 		getHeader().writeHeader(getWriter());
@@ -134,19 +133,13 @@
 		}
 	}
 
-	public void createDrawOrder(byte typ, byte sub) {
-		drawOrder.add(new DrawOrder((char) (typ | sub << 8), (char) 0, (byte) 0));
+	public void setTypParam(TypParam param) {
+		setFamilyId(param.getFamilyId());
+		setProductId(param.getProductId());
+		setCodePage(param.getCodePage());
 	}
 
-	public List<BitmapImage> getImages() {
-		return images;
+	public void setStacking(ShapeStacking stacking) {
+		this.stacking = stacking;
 	}
-
-	public List<PointInfo> getPointInfo() {
-		return pointInfo;
-	}
+}
-
-	public List<DrawOrder> getDrawOrder() {
-		return drawOrder;
-	}
-}
Index: src/uk/me/parabola/imgfmt/app/typ/DrawOrder.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/DrawOrder.java	(revision 2063)
+++ src/uk/me/parabola/imgfmt/app/typ/DrawOrder.java	(revision )
@@ -3,20 +3,27 @@
 import uk.me.parabola.imgfmt.app.ImgFileWriter;
 import uk.me.parabola.imgfmt.app.Writeable;
 
+/**
+ * The drawing order for a type and a set of subtypes.
+ *
+ * The drawing order is specified by the order of these within the file, rather than anything
+ * actually in the item.
+ */
 public class DrawOrder implements Writeable {
-	private final char typ;
-	private final char unk1;
-	private final byte unk2;
+	private final byte typ;
+	private int subTypes;
 
-	public DrawOrder(char typ, char unk1, byte unk2) {
-		this.typ = typ;
-		this.unk1 = unk1;
-		this.unk2 = unk2;
+	public DrawOrder(int typ) {
+		this.typ = (byte) typ;
 	}
 
 	public void write(ImgFileWriter writer) {
-		writer.putChar(typ);
-		writer.putChar(unk1);
-		writer.put(unk2);
+		writer.put(typ);
+		writer.putInt(subTypes);
 	}
+
+	public void addSubtype(int subtype) {
+		if (subtype > 0)
+			subTypes |= 1 << subtype;
-}
+	}
+}
Index: src/uk/me/parabola/mkgmap/scan/TokenScanner.java
===================================================================
--- src/uk/me/parabola/mkgmap/scan/TokenScanner.java	(revision 2063)
+++ src/uk/me/parabola/mkgmap/scan/TokenScanner.java	(revision )
@@ -332,8 +332,9 @@
 		skipSpace();
 		Token tok = nextToken();
 		if (val == null || !val.equals(tok.getValue()))
-			throw new SyntaxException("Expecting " + val);
+			throw new SyntaxException(this, "Expecting " + val);
 	}
+
 	public int getLinenumber() {
 		return linenumber;
 	}
Index: test/uk/me/parabola/imgfmt/app/typ/TYPFileTest.java
===================================================================
--- test/uk/me/parabola/imgfmt/app/typ/TYPFileTest.java	(revision 2063)
+++ test/uk/me/parabola/imgfmt/app/typ/TYPFileTest.java	(revision )
@@ -16,23 +16,23 @@
  */
 package uk.me.parabola.imgfmt.app.typ;
 
-import uk.me.parabola.imgfmt.FileExistsException;
-import uk.me.parabola.imgfmt.FileNotWritableException;
 import uk.me.parabola.imgfmt.FileSystemParam;
 import uk.me.parabola.imgfmt.fs.FileSystem;
 import uk.me.parabola.imgfmt.fs.ImgChannel;
 import uk.me.parabola.imgfmt.sys.ImgFS;
 
-import static org.junit.Assert.*;
 import org.junit.Test;
 
+import static org.junit.Assert.*;
+
 public class TYPFileTest {
+	
 	@Test
-	public void testWrite() throws FileNotWritableException, FileExistsException {
+	public void testWrite() throws Exception {
 		FileSystemParam params = new FileSystemParam();
 		FileSystem fs = ImgFS.createFs("test.typ", params);
 		ImgChannel channel = fs.create("XXX.TYP");
-		TYPFile typFile = new TYPFile(channel, true);
+		TYPFile typFile = new TYPFile(channel);
 		assertNotNull("typ file is created", typFile);
 	}
 }
Index: test/uk/me/parabola/mkgmap/typ/TypTextReaderTest.java
===================================================================
--- test/uk/me/parabola/mkgmap/typ/TypTextReaderTest.java	(revision )
+++ test/uk/me/parabola/mkgmap/typ/TypTextReaderTest.java	(revision )
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * 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.
+ */
+package uk.me.parabola.mkgmap.typ;
+
+import java.io.Reader;
+import java.io.StringReader;
+
+import uk.me.parabola.imgfmt.app.typ.ShapeStacking;
+import uk.me.parabola.imgfmt.app.typ.TypParam;
+
+import func.lib.ArrayImgWriter;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TypTextReaderTest {
+	private TypTextReader tr;
+	private static final int ORDER_SIZE = 5;
+
+	@Before
+	public void setUp() {
+	}
+
+	@Test
+	public void testIdSection() {
+		tr = makeTyp("[_id]\n" +
+				"FID=24\n" +
+				"ProductCode=2\n" +
+				"CodePage=99\n" +
+				"[End]");
+
+		TypParam param = tr.getParam();
+		assertEquals(24, param.getFamilyId());
+		assertEquals(2, param.getProductId());
+		assertEquals(99, param.getCodePage());
+	}
+
+	@Test
+	public void testStacking() {
+
+		tr = makeTyp("[_drawOrder]\n" +
+				"Type=0x3,1\n" +
+				"Type=0x2,2\n" +
+				"Type=0x1,4\n" +
+				"Type=0x4,2\n" +
+				"Type=0x10402,2\n" +
+				"Type=0x10405,2\n" +
+				"[End]\n");
+
+		ShapeStacking stacking = tr.getStacking();
+
+		ArrayImgWriter out = new ArrayImgWriter();
+		stacking.write(out);
+
+		byte[] buf = out.getBytes();
+		assertEquals(3, buf[0]);
+
+		assertEquals(0, buf[1 * ORDER_SIZE]);
+		assertEquals(2, buf[2 * ORDER_SIZE]);
+		assertEquals(4, buf[3 * ORDER_SIZE]);
+		assertEquals((1<<2) + (1<<5), buf[3 * ORDER_SIZE + 1]);
+	}
+
+	private TypTextReader makeTyp(String in) {
+		Reader r = new StringReader(in);
+
+		TypTextReader tr = new TypTextReader();
+		tr.read("string", r);
+		return tr;
+	}
+}
Index: src/uk/me/parabola/imgfmt/app/typ/TYPHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TYPHeader.java	(revision 2063)
+++ src/uk/me/parabola/imgfmt/app/typ/TYPHeader.java	(revision )
@@ -36,9 +36,11 @@
 	private final Section pointData = new Section();
 	private final Section lineData = new Section(pointData);
 	private final Section polygonData = new Section(lineData);
+
 	private final Section pointIndex = new Section(polygonData, (char) 4);
 	private final Section lineIndex = new Section(pointIndex, (char) 3);
 	private final Section polygonIndex = new Section(lineIndex, (char) 3);
+
 	private final Section shapeStacking = new Section(polygonIndex, (char) 5);
 
 	public TYPHeader() {
@@ -92,39 +94,30 @@
 	 * @param writer The header is written here.
 	 */
 	protected void writeFileHeader(ImgFileWriter writer) {
-		System.out.println("in file header write");
 		writer.putChar(codePage);
-		writer.putInt(pointData.getPosition());
-		writer.putInt(pointData.getSize());
 
-		writer.putInt(lineData.getPosition());
-		writer.putInt(lineData.getSize());
+		pointData.writeSectionInfo(writer);
+		lineData.writeSectionInfo(writer);
+		polygonData.writeSectionInfo(writer);
 
-		writer.putInt(polygonData.getPosition());
-		writer.putInt(polygonData.getSize());
-
 		writer.putChar(familyId);
 		writer.putChar(productId);
 
-		writer.putInt(pointIndex.getPosition());
-		writer.putChar(pointIndex.getItemSize());
-		writer.putInt(pointIndex.getSize());
-
-		writer.putInt(lineIndex.getPosition());
-		writer.putChar(lineIndex.getItemSize());
-		writer.putInt(lineIndex.getSize());
-
-		writer.putInt(polygonIndex.getPosition());
-		writer.putChar(polygonIndex.getItemSize());
-		writer.putInt(polygonIndex.getSize());
-
-		writer.putInt(shapeStacking.getPosition());
-		writer.putChar(shapeStacking.getItemSize());
-		writer.putInt(shapeStacking.getSize());
+		// Can't use Section.writeSectionInfo here as there is an unusual layout.
+		writeSectionInfo(writer, pointIndex);
+		writeSectionInfo(writer, lineIndex);
+		writeSectionInfo(writer, polygonIndex);
+		writeSectionInfo(writer, shapeStacking);
 	}
 
-	char getCodePage() {
-		return codePage;
+	/**
+	 * There is an unusual layout of the section pointers in the TYP file for the sections
+	 * that have an item size.
+	 */
+	private void writeSectionInfo(ImgFileWriter writer, Section section) {
+		writer.putInt(section.getPosition());
+		writer.putChar(section.getItemSize());
+		writer.putInt(section.getSize());
 	}
 
 	void setCodePage(char codePage) {
@@ -135,18 +128,10 @@
 		return pointData;
 	}
 
-	char getFamilyId() {
-		return familyId;
-	}
-
 	void setFamilyId(char familyId) {
 		this.familyId = familyId;
 	}
 
-	char getProductId() {
-		return productId;
-	}
-
 	void setProductId(char productId) {
 		this.productId = productId;
 	}
Index: src/uk/me/parabola/imgfmt/app/typ/TypParam.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TypParam.java	(revision )
+++ src/uk/me/parabola/imgfmt/app/typ/TypParam.java	(revision )
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * 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.
+ */
+package uk.me.parabola.imgfmt.app.typ;
+
+/**
+ * General TYP file parameters.
+ *
+ * @author Steve Ratcliffe
+ */
+public class TypParam {
+	private int familyId;
+	private int productId;
+	private int codePage;
+
+	public int getFamilyId() {
+		return familyId;
+	}
+
+	public void setFamilyId(int familyId) {
+		this.familyId = familyId;
+	}
+
+	public int getProductId() {
+		return productId;
+	}
+
+	public void setProductId(int productId) {
+		this.productId = productId;
+	}
+
+	public int getCodePage() {
+		return codePage;
+	}
+
+	public void setCodePage(int codePage) {
+		this.codePage = codePage;
+	}
+}
Index: src/uk/me/parabola/imgfmt/app/Section.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/Section.java	(revision 2063)
+++ src/uk/me/parabola/imgfmt/app/Section.java	(revision )
@@ -123,6 +123,11 @@
 			setItemSize(reader.getChar());
 	}
 
+	public SectionWriter makeSectionWriter(ImgFileWriter writer) {
+		setPosition(writer.position());
+		return new SectionWriter(writer, this);
+	}
+
 	public void writeSectionInfo(ImgFileWriter writer) {
 		writeSectionInfo(writer, false);
 	}
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to